2011-10-24 50 views
0

我已经创建了一个DLL函数,用于在C#中使用DLLImport但在调用该方法时遇到问题,因为我收到内存损坏问题;好奇的DllImport问题,当传递LONG参数内存损坏

[DllImport("mydll.dll", EntryPoint = "callinmydll")] 
public static extern int testdllcall(double *firstinput, long firstcount, double *secondoutput, long secondcount); 

这是C++库头的一部分;

extern "C" {    

mydll_API int callinmydll(double *in, long firstcount, double *out, long secondcount); 

} 

执行。

mydll_API int callinmydll(double *in, long firstcount, double *out, long secondcount) 
{ 
    for(int i =0 ; i < 10 ; i++) 
    { 
     *(out + i) = (*(in + i) + 10); 
    } 

    return 0; 
} 

现在,当我dllimport的函数调用callinmydll功能和有效的数据传递给它,这就是事情变得有趣。与firstcount一样,指针包含数据。尽管超出这一点的所有内容都已损坏。为什么?奇怪的是我重新排列我的功能是双重,double *,long,long现在腐败发生在第三个参数后面。我很好奇发生了什么,因为我传递了有效的数据;两个有效的指针,并将int转换为int64。

帮助!

+0

不能确定,但​​不是在C++长更像是在C#中,即-2147483647到2147483647 –

+0

一个int调用约定也不相符。 –

回答

4

在Win32 C中,long仍然是32位。您的C#签名使用的是64位的long。您的第二和第四个参数应该是C#签名中的int

有关更多信息,请参阅table

所以您的签名看起来像这样:

[DllImport("mydll.dll", EntryPoint = "callinmydll")] 
public static extern int testdllcall(double *firstinput, int firstcount, double *secondoutput, int secondcount); 

此外,请确保您的调用约定是正确的,因为在Ramhound的评论中指出。您的C函数看起来像使用CDecl约定,并且.NET默认为StdCall。您可以设置调用约定的属性:

[DllImport("mydll.dll", EntryPoint = "callinmydll", CallingConvention = CallingConvention.Cdecl)] 
+0

感谢您的回答,现在有道理。 – wonea

+0

如果托管代码旨在运行在32位或64位Windows环境中,那么应该如何编组一个LONG参数? – yoyo

+0

假设“长”意味着Win32长,它应该被编组为“int”。 – vcsjones