2011-10-24 47 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