2011-01-19 139 views
1

我有一個問題調用C#應用程序內的c + + dll函數。我打電話給c#裏面的函數就像這樣:在64位.net應用程序通過c + + 64位DLL pInvoke

[DllImport("cryptopp.dll")] 
public static extern IntPtr RSAEncryptString(string filename, string seed, string message); 

它被導出到C++ dll中,如下所示。

extern "C" __declspec(dllexport) const char* __cdecl RSAEncryptString(const char *pubFilename, const char *seed, const char *message); 

我能得到什麼,當我嘗試調用此方法,但是,是一個「外部組件發生異常。」例外,這是不是很具描述性,並且極其無益。

當我在導出查看器中拉出dll時,它顯示了所有其他導出的函數具有完全量化的聲明(IE public:void __cdecl CryptoPP :: X509PublicKey ::`vbase destructor'(void)__ptr64),除我正在調用的函數,它只顯示函數名稱RSAEncryptString。

這是我可以看到的唯一可能的問題,除了可能在c#端錯誤地調用帶有無效聲明的函數。我使用System.Runtime.InteropServices.Marshal錯了嗎?

請幫忙< 3,並提前致謝。

+0

返回char *的C函數非常麻煩。經典的錯誤是返回一個指向局部變量的指針。從C程序調用時有一些工作的可能性,在被調用時爲零。即使它由C代碼正確完成,並且它使用malloc()來分配字符串緩衝區,但仍然存在無法解決的內存泄漏。你需要代碼作者的幫助。 – 2011-01-19 18:01:19

回答

3

我認爲你需要的第一行更改爲:

[DllImport("cryptopp.dll", 
    CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] 

如果你想獲得非常描述性的,也可以添加這些:

public static extern IntPtr RSAEncryptString(
    [In, MarshalAs(UnmanagedType.LPStr)] string filename, 
    [In, MarshalAs(UnmanagedType.LPStr)] string seed, 
    [In, MarshalAs(UnmanagedType.LPStr)] string message); 

IIRC認爲CharSet應該照顧的編碼,但如果沒有,也可以使用MarshalAs,如上所示。


編輯:

哦,我想我明白你爲什麼仍然得到一個錯誤!你的代碼仍然存在上述問題,但它仍然錯誤,因爲你不能返回一個string對象,因爲它不是一個託管對象;您需要返回一個指針(如IntPtr),然後使用Marshal.PtrToStringAnsi

(我真的不看你的返回類型在第一次回答這個問題的時候。)

+1

仍然得到相同的例外...你的建議是有道理的,但我真的很驚訝,這是行不通的嗨 – sringer 2011-01-19 15:50:32

+0

字符串類型是`const char *`類型在技術上``LPCSTR` – Aphex 2011-01-19 15:50:46

0

看來你要const char *類型(LPCSTR)的返回值存儲到IntPtr類型(通常。用於HANDLE S,不LPSTR S)試試這個:

[DllImport("cryptopp.dll", CharSet = CharSet.Auto)] 
public static extern String RSAEncryptString(String filename, String seed, String message); 

還要記住,如果任何參數是越來越寫入,你需要它的類型前加out,即..., out String message)