2011-04-18 73 views
2

我有一些編譯爲DLL的C代碼。從C#開始,我需要將一個int數組傳遞給它,並且我需要從中獲取一個int數組。在C#和DLL之間傳遞數組數據(雙向)

這是我到目前爲止。在C#中,唯一可用的函數是bar()。它返回22並按預期寫入文件。其他人正確地寫入他們的文件,但在控制權返回給C#時拋出異常。它讀取,

「調用PInvoke函數'irhax!irhax.App :: foo'已經不平衡堆棧,這可能是因爲託管的PInvoke簽名與非託管目標籤名不匹配,請檢查調用約定和PInvoke簽名的參數匹配目標非託管簽名。「

C(該DLL):

#define IG_API __declspec(dllexport) 

IG_API void foo(int i) { 
    FILE *f = fopen("foo.txt", "a+"); 
    fprintf(f, "%d\n", i); 
    fclose(f); 
} 

IG_API int bar(void) { 
    FILE *f = fopen("bar.txt", "a+"); 
    fprintf(f, "bar!\n"); 
    fclose(f); 
    return 22; 
} 


IG_API void transmitIR(unsigned *data, int length) { 
    FILE *f = fopen("transmit.txt", "a+"); 
    for(int i = 0; i < length; ++i) 
     fprintf(f, "%d, ", data[i]); 
    fprintf(f, "\n"); 
    fclose(f); 
} 

IG_API int receiveIR(unsigned *data, int length) { 
    for(int i = 0; i < length; ++i) 
     data[i] = 4; 
    return length; 
} 

C#(來電):

[DllImport("Plugin.dll")] 
static extern void foo(int i); 

[DllImport("Plugin.dll")] 
static extern int bar(); 

[DllImport("Plugin.dll")] 
static extern void transmitIR(uint[] data, int length); 

[DllImport("Plugin.dll")] 
static extern int receiveIR(out uint[] data, int length); 

我在這裏的損失。我究竟做錯了什麼?由於我甚至無法讓foo(int)工作,所以這似乎是一個很好的開始。

回答

6

你的C代碼使用cdecl調用約定。 C#代碼使用stdcall。

所有DLLImport屬性應該是:

[DllImport("Plugin.dll", CallingConvention=CallingConvention.Cdecl)] 

你當然可以交替切換的C代碼使用__stdcall到STDCALL。但要確保你只做這其中的一個!

receiveIR不需要out。您應該聲明:

static extern int receiveIR(uint[] data, int length); 
1

您是否知道C函數的調用約定?就像錯誤一樣,這可能是不匹配的。默認調用約定是stdcall,但如果這些函數使用cdecl約定,則可能會出現此錯誤。嘗試

[DllImport("Plugin.dll", CallingConvention=CallingConvention.Cdecl)] 
static extern void foo(int i);