2012-10-19 20 views
1

我有一個C++ DLL,從C#控制檯應用程序被調用如下所示。從VS中的C#調用C++ DLL失敗。在VS之外運行EXE,它工作

當在Visual Studio中運行以調試它時,它會拋出一個異常說明堆棧不穩定並檢查方法參數是否正確。但是,如果我從Windows資源管理器的VS之外運行* .exe,則會按預期方式將數據返回到屏幕。

我怎樣才能讓它在Visual Studio中運行?

感謝

**From the C++ header file:** 
#ifdef RFIDSVRCONNECT_EXPORTS 
#define RFID_CONN_API __declspec(dllexport) 
#else 
#define RFID_CONN_API __declspec(dllimport) 
#endif 

RFID_CONN_API BSTR rscListDevices(long showall) ; 


[DllImport("MyDLL.dll")] 
[return: MarshalAs(UnmanagedType.BStr)] 
public static extern string rscListDevices(int showall); 

static void Main(string[] args) 
{ 
    string data= rscListDevices(0); 
    Console.WriteLine(data); 
    Console.ReadKey(); 
} 
+0

C/C++頭文件中的正確方法簽名是什麼?問題可能是您的P/Invoke簽名不正確。 – Ben

+0

RFID_CONN_API BSTR rscListDevices(long showall); – Jon

+0

RFID_CONN_API是如何定義的? –

回答

3

首先,確保你使用相同的調用約定在雙方C++C#

我懷疑設置了/Gd編譯器選項(因爲它是默認設置的),所以__cdecl被用作未標記函數的默認調用約定。

你可以在你的C#代碼或者specifing相同的調用約定修復崩潰:

[DllImport("MyDLL.dll", CallingConvention=CallingConvention.Cdecl))] 
[return: MarshalAs(UnmanagedType.BStr)] 
public static extern string rscListDevices(int showall); 

或改變rscListDevices的調用約定__stdcall(這是在C#中的默認值):

RFID_CONN_API BSTR __stdcall rscListDevices(long showall) ; 

您還可以通過手動或使用「項目屬性」對話框將編譯器選項從/ Gd更改爲/ Gz,將__stdcall設置爲C++ DLL中未標記函數的默認調用約定: changing the default calling convention in Visual Studio

但是,如果您真的想要禁用MDA,您可以轉到Debug-> Exceptions並取消選中Managed Debugging Assistance。

你可以閱讀更多關於pInvokeStackImbalance和MDA herehere

+0

謝謝。我寧願得到C++引用,如果需要更改C++代碼以使其正常工作。有任何想法嗎? – Jon

+2

@Jon,沒有正確或錯誤的C++調用約定,重要的是C++和C#約定匹配。 – Ben

+0

適用於VS2012中的CallingConvention,但不適用於VS2010。 VS2010返回一個空字符串 – Jon

相關問題