简体   繁体   中英

Can't use/debug unmanaged DLL from C#

I have a C# application and a C++ DLL, both x86. The Application is the startup project, the DLL project is inside the same solution and is referenced as a project. The C++ DLL outputs its PDB file with the same name as the DLL inside the Debug folder of the Application.

I have a function called SomeFunction that I'm trying to execute in C#. When the code reaches that line, it stops there. The UI of the C# application continues to be responsive, but the breakpoint never leaves that line (and that's in Form_Load).

If I try to set the DLL as startup project and tell it to execute the C# application, then C# will crash at that line with: System.EntryPointNotFoundException: Unable to find an entry point named 'SomeFunction' in DLL 'SomeDLL.dll'.

This is the declaration of the function that I'm trying to call:

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

This is the function's declaration from the C++ header:

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

This is how I call it from C#:

var someAnswer = SomeFunction(_hwnd);

UPDATE : since the discussion below could take some time to read, here's the answer in the nutshell: I was missing an extern "C". Also, in order to debug the DLL (which was also a problem), the project needs to support native debugging both from C++ and C#, here's an excellent list that I went through and at the end it was all good!

No Symbols loaded in mixed C# C(win32) project using VS2010

I suspect the problem that it won't set the breakpoint beforehand is that the DLL is loaded on demand via p-invoke. If VS doesn't think the DLL is a dependency, it may not allow you to set the breakpoint beforehand.

You could add a DebugBreak to your c++ code. Then simply run your app, don't debug it. Then when it executes this statement, you will get a Just in time debugging alert allowing you to jump into the c++ debugger.

C++ as startup

Alternatively, you could make the DLL the startup project, but change the debug settings so that it launches an external process - in this case your app .exe.

This time however, you don't need the DebugBreak(), just a regular breakpoint.

Now when you debug, your DLLs symbols are loaded thus allowing the break points to work.

I used this trick a lot with ActiveX/COM.

  1. Run code that calls SomeFunction to ensure unmanaged .dll is loaded
  2. Go into Debug -> Windows -> Modules and check the .dll path and symbols status. You can try to load symbols in context menu of your c++ dll in that window.

(very often happens that .net loads different (not expected) version of unmanaged .dll)

Now I'm pretty sure that the problem is that your exported function name is mangled. Try to define function like this:

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

In C#:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM