C DLL在C中不起作用,但在C+中起作用+; 我不理解下面的代码,它是用我的C++工作的,但是它不想用C语言工作。 你能帮我理解这里的错误吗?我想我不得不说,我对C#是完全陌生的
在我的C中------->C DLL在C中不起作用,但在C+中起作用+; 我不理解下面的代码,它是用我的C++工作的,但是它不想用C语言工作。 你能帮我理解这里的错误吗?我想我不得不说,我对C#是完全陌生的,c#,c,dll,unsafe,C#,C,Dll,Unsafe,在我的C中-------> 注:实际上,当我从C++调用C函数时,我的DLL确实起作用,但是正如我上面所说的,在C语言中,C语言中的字符串变量不是打印错误的SbOLS,而是DLL“工作”。 提前感谢 最好的办法是将C函数的PInvoke签名改为使用ref IntPtr: [DllImport("My_C_Lib.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void get(ref IntPtr
<强>注:实际上,当我从C++调用C函数时,我的DLL确实起作用,但是正如我上面所说的,在C语言中,C语言中的字符串变量不是打印错误的SbOLS,而是DLL“工作”。
提前感谢 最好的办法是将C函数的PInvoke签名改为使用
ref IntPtr
:
[DllImport("My_C_Lib.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void get(ref IntPtr buffer);
要调用此函数,您需要实例化一个IntPtr并通过引用将其传递给C函数(这对于在C中声明一个char*
并通过地址传递它是很有帮助的):
现在,你需要。要执行此操作,必须复制字符串
string str = Marshal.PtrToStringAnsi(ptr);
- 确保理解ANSI和Unicode字符串之间的区别,并确保调用适当的
变量PtrToString…()
- 请注意,由于是由非托管代码分配的,.NET运行时将不会为您管理分配的
。您必须使用适合DLL的任何机制来释放它(理想情况下,DLL应该提供相应的释放函数,因为它是首先分配内存的人)ptr
- 为保证健壮性,请添加适当的错误/空指针检查。确保
成功,并且get()
不是ptr
IntPtr.Zero
- 为避免泄漏,如果在
返回的时间和释放指针的时间之间有任何代码抛出异常的可能性,则该代码就是您的朋友get()
(旁白:请注意,
get
在C#中是一个标识符,因此虽然您可以将其用作标识符,但为了避免混淆,您可能不希望使用它。)代码几乎正确,但
C DLL在C中不起作用,但在C中起作用++
< C和C++ >代码> char >是8位数据类型。在C#中,char
是一种16位数据类型
<>这意味着C++希望由*buffer = "H\0e\0l\0l\0o\0\0\0";
*buffer = (char*)calloc(6, sizeof(char));
...
*buffer = "Hello";
。。。而且它有效
当然,您也可以使用现代C编译器的“宽字符串”函数:
void get(wchar_t** buffer)
{
*buffer = L"Hello";
}
顺便说一下
您的程序中还有一个错误:
*buffer = "H\0e\0l\0l\0o\0\0\0";
*buffer = (char*)calloc(6, sizeof(char));
...
*buffer = "Hello";
这毫无意义:
第二行(
*buffer=“Hello”
)不会将字符串复制到calloc
分配的内存中,但它会将字符串的地址“Hello”
写入变量buffer
,并且calloc
返回的值(地址)被覆盖(并丢失).C#中的char
与C#中的char
是不同的。不要在C#中使用原始指针,请使用。谢谢,您能告诉我在这种情况下如何使用PInvoke吗?请注意,这里存在内存泄漏。封送对使用原始指针和分配器的非托管代码的调用,并且使用了C#本机不支持的字符串编码,这很难做到正确。这不是初学者的任务。请一位专家,或者从一个更简单的问题开始。这不是一个指导人们学习复杂学科的网站;读一些关于互操作和编组的书。关于平沃克的圣经是亚当·内森的书
*buffer = (char*)calloc(6, sizeof(char));
...
*buffer = "Hello";