【发布时间】:2021-04-07 23:01:57
【问题描述】:
我正在尝试打开从我的 C# 项目中的 Dll 导出的 char*。
由于代码太多,我就写一个短代码,和我正在做的代码类似。
C++:
__declspec(dllexport) typedef struct Kid {
char* _name;
int _age;
int _grade;
} Kid;
Kid get_default_kid()
{
char name[] = { "Quinn" };
return Kid{
name, 2,7
};
}
extern "C" __declspec(dllexport) Kid get_default_kid();
C#:
public struct Kid
{
public string _name;
public int _age;
public int _grade;
}
private const string Dll2 = @"C:\Users\Me\source\repos\Tom\x64\Release\JerryDll.dll";
[DllImport(Dll2, CallingConvention = CallingConvention.Cdecl)]
private static extern Kid get_default_kid();
public static void Main(string[] args){
Kid defaultKid = get_default_kid();
Console.WriteLine(defaultKid._name);
Console.WriteLine(defaultKid._age);
Console.WriteLine(defaultKid._grade);
}
此代码在控制台中写入一些随机字符,例如“♠”,而不是从 dll 中导出的名称。
我尝试过的:
尝试将char* 导入为IntPtr,然后使用:
Marshal.PtrToStringAnsi()/BSTR/Auto/Uni
和Marshal.ReadIntPtr 在尝试使用上面的行读取它之前。
我尝试在 C# 中将字符串转换为 UTF-8。
在谷歌中搜索了很多。
【问题讨论】:
-
在现实世界中,它是 very、very、very 复杂的。问题是“通常” C 端字符串名称会以某种方式分配(如 malloc),因此您需要相应的
FreeKid(Kid*)... 在此示例中Quinn是一个 C 字符串文字,所以你永远不应该释放它...... :-) -
nameinget_default_kid是一个局部变量,当函数返回时会消失。 -
还有内存所有权的问题:见limbioliong.wordpress.com/2011/06/16/…
-
@Manuel 所以这意味着,当函数返回指向该字符(字符串)数组的指针时,该数组将消失。因此,当我的 C# 项目试图取消引用该指针时,那里什么都没有。我明白了,非常感谢。
-
Manuel 帮我解决了我的问题。如果有人在一般情况下和最佳实践中添加一个关于如何在 c# 中从 dll 导入 char* 的问题的答案,那就太好了。所以我和任何可能需要帮助的人都可以阅读和学习。谢谢。
标签: c# c++ marshalling c-strings char-pointer