繁体   English   中英

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

[英]How to set up a C++ function so that it can be used by p/invoke?

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

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

extern bool __cdecl TestFunc()
{
  return true;
}

最初我只是这个,但它也不起作用:

bool TestFunc()
{
  return true;
}

然后在C#方面,我有:

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

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

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

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

您将要使用extern "C"以及__declspec(export) ,如下所示:

extern "C" _declspec(dllexport)  bool TestFunc()
{
    return true;
}

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

扩展里德的正确答案。

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

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

void TestFunc(std::string input);

即使添加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);
}

您必须使用extern "C"公开此函数,否则名称会被破坏。

C ++编译器修改函数的名称以包含有关参数和返回类型的信息。 这称为名称修改。 另一方面,C编译器不会破坏您的函数名称。

您可以告诉C ++编译器使用extern "C"作为C编译器:

extern "C" __declspec(dllexport) bool TestFunc { return true; }

要使用P / Invoke从C#调用函数,不得破坏您的名称。 因此,您实际上可以将C函数导出到C#。 如果希望在C ++中实现该功能,可以编写一个只调用实现该功能的C ++函数的C函数。

做这样的事情:

#define EXPORT extern "C" __declspec(dllexport)

然后使用EXPORT关键字声明任何函数,例如c ++函数

BOOL getString(TCHAR* string, DWORD size);

会成为

EXPORT BOOL getString(TCHAR* string, DWORD size);

然后是有趣的部分:转到VS控制台并输入:

dumpbin /EXPORTS <PATH_TO_GENERATED_DLL>

并且你会看到所有易于导出的函数的错误名称和序数,那么它只是一个问题

使用Win32平台和适当的位(例如x86或x64)构建选项构建所有项目。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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