如何设置C++函数以便p/invoke可以使用它?

x40*_*000 8 c# c++ pinvoke dllimport extern

希望这是一个无脑的简单问题,但它表明我缺乏C++专业知识.我是一名C#程序员,过去我和其他人的C++/C dll一起完成了P/Invoke的大量工作.但是,这次我决定自己编写一个包装器C++ DLL(非托管),然后从C#调用我的包装器dll.

我遇到的问题是我无法定义可以通过p/invoke找到的C++函数.我不知道这是什么语法,但这是我到目前为止所做的:

extern bool __cdecl TestFunc()
{
  return true;
}
Run Code Online (Sandbox Code Playgroud)

最初我只是这个,但它也没有用:

bool TestFunc()
{
  return true;
}
Run Code Online (Sandbox Code Playgroud)

然后在C#方面,我有:

    public const string InterfaceLibrary = @"Plugins\TestDLL.dll";

    [DllImport( InterfaceLibrary, CallingConvention = CallingConvention.Cdecl,
        EntryPoint = "TestFunc" ), SuppressUnmanagedCodeSecurity]
    internal static extern bool TestFunc();
Run Code Online (Sandbox Code Playgroud)

所有东西都编译,但是当我执行这个C#p/invoke调用时,我得到一个System.EntryPointNotFoundException:无法在DLL'Plugins\TestDLL.dll'中找到名为'TestFunc'的入口点.

当然,这在C++端必须非常简单,我只是不知道它的语法.

Ree*_*sey 13

你要使用extern "C",以及__declspec(export),就像这样:

extern "C" _declspec(dllexport)  bool TestFunc()
{
    return true;
}
Run Code Online (Sandbox Code Playgroud)

有关完整详细信息,请参阅编组类型上的MSDN.


Jar*_*Par 7

扩展里德的正确答案.

通过PInvoke公开C++函数时可能遇到的另一个问题是使用无效类型.PInvoke实际上只支持原始类型和普通旧数据结构/类类型的编组.

例如,假设TestFunc具有以下签名

void TestFunc(std::string input);
Run Code Online (Sandbox Code Playgroud)

即使添加extern"C" __declspec(dllexport)也不足以暴露C++函数.相反,您需要创建一个辅助函数,它只暴露PInvoke兼容类型,然后调用main函数.例如

void TestFunc(const std::string& input) { ... }

extern "C" _declspec(dllexport)  void TestFuncWrapper(char* pInput) {
  std::string input(pInput);
  TestFunc(input);
}
Run Code Online (Sandbox Code Playgroud)