2015-12-15 40 views
0

我編碼CryptoPP的包裝,其將通過C#應用程序中使用。 我的問題是,當使用PInvoke在包裝中調用特定函數時,會引發異常「試圖讀取或寫入受保護的內存......」。 它們都被編譯爲x64。的P/Invoke「受保護的內存」異常上/ MT或/ MD

現在..奇怪的部分是,如果我使用/ MTD或/ MDd運行時編譯我的包裝,調用不會失敗,一切正常。但將運行時更改爲/ MT或/ MD會引發上述異常。

我不能用我的客戶使用/ MTD或/ MDD公務選項,因爲它需要大量的DLL資源的安裝或分配到用戶機器。

CPP代碼:

extern "C" __declspec(dllexport) int CryptBlock(bool mode, unsigned char type, unsigned char *inData, unsigned char *outData, int dataLen, unsigned char *key, int keyLen); 

C#的PInvoke:以各種方式

[DllImport("mydll.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] 
    public static extern int CryptBlock(bool mode, byte type, IntPtr inData, IntPtr outData, int dataLen, IntPtr key, int keyLen); 

我試圖修改我P /調用代碼: [輸入,輸出],[停止],參考文獻, ref byte [],byte []等...仍拋出異常。

等待我的救星...

謝謝。

+1

可能是某處你CryptBlock代碼中的錯誤,只有當不使用/ MTD或/ MDD恰好被觸發:這些都是調試庫,內存可能會在比較釋放模式(IIRC調試CRT庫以不同的方式進行初始化傾向於將內存初始化爲調試中的所有0,但不是在釋放中,因此假設您有一個單元化變量,然後使用它來索引一個數組--BAM)。也許啓用所有運行時檢查就會發現問題,另請參閱http://stackoverflow.com/questions/186237/program-only-crashes-as-release-build-how-to-debug – stijn

+0

你是如何調用'CryptBlock()'?可能你的'dataLen'或'keyLen'是錯誤的。 – dbc

回答

0

考慮使用託管和非託管代碼之間的橋樑。 它可以更容易地調試...

實施例:

C++非託管代碼:

class ExampleCpp 
{ 
private: 

    int id; 

public: 

    ExampleCpp(); 
    ~ExampleCpp(); 

    const int getId(); 

};  

C++託管代碼:

public ref class ExampleManagedCpp 
{ 
private: 
    ExampleCpp* pImpl; 

public: 

    ExampleManagedCpp(); 
    ~ExampleManagedCpp(); 
    !ExampleManagedCpp(); 
}; 

http://www.codeproject.com/Articles/868230/Cplusplus-CLI-Accessing-a-managed-type-from-unmana

http://blogs.msdn.com/b/soultech/archive/2010/07/27/cli-c_2b002b00_-to-c_2300_-hello-world.aspx

1

你是對的,你不能分發調試運行時,但實際上這個問題並不完全是你的想法。該許可證不允許重新分配調試運行時。

最可能的解釋是事實,你的代碼有缺陷。缺陷不會在調試運行時顯現的事實簡直就是偶然。所以正確的做法是找出缺陷並修復它。

相關問題