23

我用开发 C++ 编写了一个 DLL。DLL 的名称是“DllMain.dll”,它包含两个函数:HelloWorldShowMe. 头文件如下所示:

DLLIMPORT  void HelloWorld();
DLLIMPORT void ShowMe();

源文件如下所示:

DLLIMPORT void HelloWorld ()
{
  MessageBox (0, "Hello World from DLL!\n", "Hi",MB_ICONINFORMATION);
}

DLLIMPORT void ShowMe()
{
 MessageBox (0, "How are u?", "Hi", MB_ICONINFORMATION);
}

我将代码编译成 DLL 并从 C# 调用这两个函数。C# 代码如下所示:

[DllImport("DllMain.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void HelloWorld();

[DllImport("DllMain.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void ShowMe();

当我调用函数“HelloWorld”时,它运行良好并弹出一个消息框,但是当我调用该函数时ShowMe,它EntryPointNotFoundException会发生。如何避免此异常?我需要extern "C"在头文件中添加吗?

4

3 回答 3

17

VS 2012 中的以下代码运行良好:

#include <Windows.h>
extern "C"
{
    __declspec(dllexport) void HelloWorld ()
    {
        MessageBox (0, L"Hello World from DLL!\n", L"Hi",MB_ICONINFORMATION);
    }
    __declspec(dllexport) void ShowMe()
    {
        MessageBox (0, L"How are u?", L"Hi", MB_ICONINFORMATION);
    }
}

注意:如果我删除extern "C"我得到异常。

于 2013-05-02T10:28:38.083 回答
6
using System;
using System.Runtime.InteropServices;

namespace MyNameSpace
{
    public class MyClass
    {
        [DllImport("DllMain.dll", EntryPoint = "HelloWorld")]
        public static extern void HelloWorld();

        [DllImport("DllMain.dll", EntryPoint = "ShowMe")]
        public static extern void ShowMe();
    }
}
于 2013-05-02T10:52:33.280 回答
3

有帮助的事情:

  • 的:extern "C" { 函数声明 here in h file } 将禁用 C++ 名称编码。所以c#会找到函数

  • 对 C 声明使用 __stdcall 或在 C# 声明中使用 CallingConvention.Cdecl

  • 可能使用 BSTR/_bstr_t 作为字符串类型并使用其他 vb 类型。http://support.microsoft.com/kb/177218/EN-US

  • 下载“PInvoke Interop Assistant” https://clrinterop.codeplex.com/releases/view/14120 从 .h 文件中的第 3 个选项卡 = c# 声明中粘贴函数声明。替换为 dll 文件名。

于 2015-01-09T02:32:46.260 回答