我已經閱讀了其他類似的問題,但他們沒有解決這個問題。我有一個帶touppercase函數的舊C庫(作爲例子)。這需要一個char *並返回一個char *。但是,返回的指針是一個指向同一個字符串的指針(不要問我,我沒有寫它)。使用char *參數調用C DLL函數使用P/Invoke
功能如下:
__declspec(dllexport)
char * __cdecl touppercase(char *ps_source)
{
char *ps_buffer = NULL;
assert (ps_source != NULL);
ps_buffer = ps_source;
while (*ps_buffer != '\0')
{
*ps_buffer = toupper(*ps_buffer);
ps_buffer++;
}
*ps_buffer = '\0';
return (ps_source);
}
的C#代碼來聲明這個樣子:
[DllImport("mydll.dll", EntryPoint = "touppercase",
CharSet = CharSet.Ansi, ExactSpelling = true,
CallingConvention = CallingConvention.Cdecl)]
private static extern System.IntPtr touppercase(string postData);
在我的應用程序這個調用看起來像
string sTest2 = Marshal.PtrToStringAnsi(to_uppercase(sTest));
然而sTest2最終只是一個隨機字符串。
我添加了一個測試函數給具有相同參數的同一個dll,但是這個在本地分配了內存並且複製了字符串。這工作正常。爲什麼現在的原始版本有效?
注意:更新dll庫本身不是一個選項。
調用此函數後sTest會發生什麼?它會改變嗎? – 2011-05-27 14:19:01
你爲什麼要宣佈調用約定。默認情況下C#使用調用約定而不是標準約定(C/C++)。你已經改變了C庫中的約定。如果C代碼沒有聲明爲默認值之外的其他值,則只需更改約定。 – 2011-05-27 14:41:29
@ramhound:明確指定導出函數的調用約定是最安全的。您不希望導出受'/ Gr'或'/ Gz'的影響。 – 2011-05-27 16:02:12