从不带 extern "C" 的 dll 导出 C++ 函数

问题描述 投票:0回答:4

目标: 应用程序应该能够使用 LoadLibrary 动态加载 dll,并使用 GetProcAddress 调用其导出的函数。

我的 dll 类有一个返回该类类型的 unique_ptr 的函数。

我想导出这个函数,以便应用程序可以在成功加载dll后使用getProcAddress调用这个函数。

使用 extern "C" 将不允许在函数签名中使用 C++ 类(在本例中为 unique_ptr 类模板)。

我知道,如果不使用 extern "C",它将使用损坏的名称导出函数(通过 __declspec(dllexport) )。

客户端在调用 getProcAddress 期间不会知道损坏的名称,那么客户端将如何调用此函数?

有办法导出这样的函数吗?

c++ dllexport
4个回答
3
投票

是的,老式的方式。按名称查找函数是“现代”方式(尽管它早于 Windows 95)。旧的方法是按序号查找它们。

您需要提供一个 模块定义文件 以及

EXPORTS
来对您的函数进行编号。


0
投票

如果您想从 DLL 导出 C++ 函数而不使用

extern "C"
,您仍然可以通过使用称为名称修饰或名称修饰的技术来实现。名称修饰根据函数签名等因素以特定的方式修改函数名称。

要允许客户端使用

GetProcAddress
调用函数而不知道损坏的名称,您可以使用称为名称导出转发的技术。通过这种方法,您可以创建一个单独的 C 风格包装函数,该函数具有众所周知的名称并在内部调用实际的 C++ 函数。

以下是如何从 DLL 导出 C++ 函数并提供 C 风格包装器供客户端使用的示例:

// DLL header file
#ifdef MYLIB_EXPORTS
#define MYLIB_API __declspec(dllexport)
#else
#define MYLIB_API __declspec(dllimport)
#endif

// Forward declaration of C-style wrapper function
extern "C" MYLIB_API void entryPoint_wrapper();

// Actual C++ function definition
MYLIB_API void entryPoint();

// C-style wrapper function implementation
void entryPoint_wrapper()
{
    entryPoint();
}

通过这种方法,客户端可以使用已知名称

entryPoint_wrapper
GetProcAddress
来调用
entryPoint_wrapper
函数。包装函数将在内部调用实际的
entryPoint
函数。

请注意,您需要使用

entryPoint
从 DLL 导出 C++ 函数 (
entryPoint_wrapper
) 和 C 样式包装函数 (
__declspec(dllexport)
)。


0
投票

使用 extern "C" 将不允许在函数签名中使用 C++ 类(在本例中为 unique_ptr 类模板)

这根本不是真的。使用

extern "C"
导出您喜欢的任何签名。课程、参考文献等等。它只是有效


0
投票

我只使用输出参数就解决了这个问题

void plus( std::string& out, const std::string& a, const std::string& b)
{
    out = a + b;
}
© www.soinside.com 2019 - 2024. All rights reserved.