簡體   English   中英

無法使用/調試來自C#的非托管DLL

[英]Can't use/debug unmanaged DLL from C#

我有一個C#應用程序和一個C ++ DLL,兩者均為x86。 該應用程序是啟動項目,該DLL項目在同一解決方案中,並且被引用為一個項目。 C ++ DLL輸出其PDB文件,其名稱與該應用程序的Debug文件夾中的DLL相同。

我有一個要在C#中執行的名為SomeFunction的函數。 當代碼到達該行時,它在那里停止。 C#應用程序的UI繼續保持響應狀態,但是斷點從不離開該行(並且該行位於Form_Load中)。

如果我嘗試將DLL設置為啟動項目並告訴其執行C#應用程序,則C#將在該行崩潰,並帶有以下內容:System.EntryPointNotFoundException:無法在DLL'SomeDLL.dll'中找到名為'SomeFunction'的入口點。

這是我要調用的函數的聲明:

[DllImport("SomeDLL.dll", EntryPoint = "SomeFunction", CallingConvention = CallingConvention.Cdecl)]
public static extern int SomeFunction(IntPtr hwnd);

這是C ++標頭中的函數聲明:

#define MYDLL_API __declspec(dllexport)
MYDLL_API extern int SomeFunction(HWND hWnd);

這就是我從C#調用它的方式:

var someAnswer = SomeFunction(_hwnd);

更新 :由於下面的討論可能需要一些時間才能閱讀,因此簡而言之,這就是答案:我錯過了extern“ C”。 此外,為了調試DLL(這也是一個問題),該項目需要支持C ++和C#的本機調試,這是我經歷的一個很棒的清單,最后一切都很好!

使用VS2010在混合C#C(win32)項目中未加載任何符號

我懷疑它不會事先設置斷點的問題是DLL是通過p調用按需加載的。 如果VS認為DLL不是依賴項,則可能不允許您事先設置斷點。

您可以將DebugBreak添加到您的c ++代碼中。 然后只需運行您的應用程序,而不調試它。 然后,當它執行此語句時,您將收到“ 及時調試”警報,使您可以跳入c ++調試器。

C ++作為啟動

或者,您可以使DLL成為啟動項目,但可以更改調試設置,以使其啟動外部進程-在本例中為您的應用程序.exe。

但是這一次,您不需要DebugBreak(),只需一個常規斷點即可。

現在,當您進行調試時,將加載DLL符號,從而使斷點起作用。

我在ActiveX / COM上經常使用此技巧。

  1. 運行調用SomeFunction代碼以確保加載了非托管.dll
  2. 進入調試-> Windows->模塊並檢查.dll路徑和symbols狀態。 您可以嘗試在該窗口的c ++ dll的上下文菜單中加載symbols

(.net經常會加載非托管.dll的不同(非預期)版本)

現在,我很確定問題出在您的導出函數名稱是否整齊。 嘗試這樣定義函數:

extern "C" MYDLL_API int PASCAL SomeFunction(HWND hWnd);

在C#中:

[DllImport("SomeDLL.dll")]
public static extern int SomeFunction(IntPtr hwnd);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM