[英]DLLImport(C code) C# Attempted to read or write protected memory. This is often an indication that other memory is corrupt”
[英]Trouble with C#<->C++ DLLImport “Attempted to read or write protected memory.”
我有一個C ++ DLL,其中有一個函數,我試圖從C#應用程序調用。
這是C ++頭文件中的代碼
extern "C" _declspec(dllexport) int LabelStoringSSDsim(int devNum, UCHAR serial[40], UCHAR wwn[40],
UCHAR ConfigID[5], UCHAR FrmRev[8], UCHAR DevName[40], int eCode);
這是C ++源文件中的代碼
int LabelStoringSSDsim(int devNum, UCHAR serialLbl[40], UCHAR wwnLbl[40],
UCHAR ConfigID[5], UCHAR FrmRev[8], UCHAR DevName[40], int eCode)
{
string strConfigID="12111"; //5 bytes
string strFrmRev="1.25...."; //8 bytes
string strDevName="ABC-123................................."; //40 bytes
for (int i=0;i<5;i++)
ConfigID[i] = strConfigID[i];
for (int i=0;i<8;i++)
FrmRev[i] = strFrmRev[i];
for (int i=0;i<40;i++)
DevName[i] = strDevName[i];
return eCode;
}
這是C#相關代碼
[DllImport("LabelStoring.dll")]
static extern int LabelStoringSSDsim(
int devNum,
byte[] strserial,
byte[] strwwn,
[In] ref byte[] ConfigID,
[In] ref byte[] FrmRev,
[In] ref byte[] DevName,
int eCode
);
int errNum = LabelStoringSSDsim(devNum, bserial, bwwn, ref ConfigID, ref FrmRev, ref DevName, 123123);
因此,當我到達最后一段代碼時,我得到“嘗試讀取或寫入受保護的內存。這通常表明其他內存已損壞。” 錯誤。
我沒有像這樣導入DLL的經驗,我已經做了很多搜索,但似乎無法找到問題的解決方案。
我嘗試從頭開始用一個簡單的函數返回一個整數,這是有效的。 然后我為我添加了一個int來傳遞給函數,它仍然有效。 然后我添加了一個字節數組供我通過,這有效。 然后我試圖將該字節數組轉換為引用,但它失敗了。 所以我的猜測是我正在錯誤地收回數據。
任何幫助是極大的贊賞。
嘗試將[In]
更改為[In, Out]
。 我也不確定在一個參數上同時使用ref
和[In, Out]
關鍵字。 (編輯:Hans Passant在下面的評論中很好地解釋了兩者之間的差異。)
有關詳細信息,請參閱此MSDN文章 ,特別是段落,“默認情況下,由於性能原因,值傳遞的引用類型(類,數組,字符串和接口)被封送為In參數。除非您看到這些類型的更改將InAttribute和OutAttribute(或只是OutAttribute)應用於方法參數。“
在升級到Windows 7之后,我開始定期在本地互操作程序中獲得此異常。如果我在XP兼容模式下運行我的應用程序,代碼一直在XP上運行並且Win 7上的問題更少。
經過一些研究和實驗,我發現我得到這個異常的原因與調用返回字符串的本機函數(WCHAR *)有關。
我不相信目前有一個解決方案,因為即使更新到.Net 3.5也沒有解決問題......但是我確實找到了以下解決方法。
什么在XP上有效但在Win 7上不起作用的示例:
[DllImport("NativeBin.dll")]
public static extern String GetWCharStr();
在Win 7和XP上對我有用的示例:
[DllImport("NativeBin.dll")]
private static extern IntPtr GetWCharStr();
public static String GetString()
{
return Marshal.PtrToStringUni(GetWCharStr());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.