2014-09-05 92 views
0

我尝试调用C#中用C编写的dll方法。调用C DLL中的方法失败

这是C方法:

​​

这也是我尝试调用它的方式。

[DllImport(EntryPoint = "c_ata", CallingConvention = CallingConvention.Cdecl)] 
private static extern string cAta(byte[] c, long c_len, byte[] b, long b_len); 

问题是我没有得到任何错误,当我尝试运行或调试我的NUnit测试。

我不是很熟悉C语法,所以问题是?我的电话语法是否正确(理论上)?

+0

size_t参数需要是IntPtr。字符串返回值也需要是IntPtr,否则编组人员会试图销毁字符串。这是非常少见的,C代码通常不会使用CoTaskMemAlloc()来分配可以在另一个模块中安全释放的内存。这很可能是不可避免的内存泄漏。使用Marshal.PtrToStringAnsi()转换IntPtr。编写一个测试程序,数百万次调用该函数,观察内存使用情况。 – 2014-09-05 23:19:11

回答

0

在C#中,long指定一个64位整数。 C代码中的size_t是64位吗?如果不是,PInvoke签名应该改为使用int而不是long。

如果声明一个PInvoke签名以返回一个字符串,则编组器将从返回的指针创建一个字符串,然后在指针上调用CoTaskMemFree。这只适用于指针最初分配给CoTaskMemAlloc的情况。如果本地端自己清理内存,则应该声明PInvoke返回一个IntPtr,然后您可以使用Marshal.PtrToStringAnsi或等价物创建一个字符串。

+0

谢谢你,Marshal.PtrToStringAnsi已经做到了 – user4013391 2014-09-06 06:55:01