无法从C#使用/调试非托管DLL

时间:2016-08-07 15:03:15

标签: c# c++ debugging mixed-mode

我有一个C#应用程序和一个C ++ DLL,都是x86。 Application是启动项目,DLL项目位于同一解决方案中,并作为项目引用。 C ++ DLL输出其PDB文件,其名称与应用程序的Debug文件夹中的DLL相同。

我有一个名为SomeFunction的函数,我试图在C#中执行。当代码到达该行时,它就会停在那里。 C#应用程序的UI继续响应,但断点永远不会离开该行(以及Form_Load中的那个)。

如果我尝试将DLL设置为启动项目并告诉它执行C#应用程序,则C#将在该行崩溃:System.EntryPointNotFoundException:无法找到名为' SomeFunction'的入口点。在DLL' SomeDLL.dll'。

这是我试图打电话的功能声明:

[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);

更新:由于下面的讨论可能需要一些时间来阅读,因此简而言之,答案是:我错过了一个外部人员" C"。另外,为了调试DLL(这也是一个问题),项目需要支持来自C ++和C#的本机调试,这是一个很好的列表,我经历过,最后一切都很好!

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

2 个答案:

答案 0 :(得分:1)

我怀疑它事先没有设置断点的问题是DLL是通过p-invoke按需加载的。如果VS并不认为DLL是依赖项,则可能不允许您事先设置断点。

您可以在c ++代码中添加DebugBreak。然后只需运行您的应用程序,不要调试它。然后,当它执行此语句时,您将获得及时调试警报,允许您跳转到c ++调试器。

C ++ as startup

或者,您可以将DLL作为启动项目,但更改调试设置以便启动外部进程 - 在这种情况下是您的应用程序.exe。

但是,这一次,您不需要DebugBreak(),只需要一个常规断点。

现在,在调试时,会加载DLL符号,从而允许断点起作用。

我在ActiveX / COM上经常使用这个技巧。

答案 1 :(得分:1)

  1. 运行调用SomeFunction的代码以确保加载非托管.dll
  2. 进入调试 - > Windows - >模块并检查.dll路径和symbols状态。您可以尝试在该窗口中的c ++ dll的上下文菜单中加载symbols
  3. (通常会发生.net加载不同(非预期)版本的非托管.dll)

    现在我很确定问题是导出的函数名称被破坏了。 尝试定义这样的函数:

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

    在C#中:

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