gpt4 book ai didi

xcode - 如何在 macOS 上的 Xcode 中的动态库中从 C++ 中解开导出的符号

转载 作者:行者123 更新时间:2023-12-03 23:15:15 24 4
gpt4 key购买 nike

我一直在尝试用 C++ 开发一个可以在应用程序中运行时加载的动态库。我终于让它工作了,但它有点难看。我有一个函数,它将指向 C++ 类的指针作为参数,如下所示:

bool registerGrindPlugin( Grind::PluginManager* mgr );
但当然它被导出为:
_Z19registerGrindPluginPN5Grind13PluginManagerE
我尝试了一个带有简单函数的 .c 文件,它导出为“registerGrindPlugin”,但当然我不能以这种方式将 C++ 类作为参数传递。
所以......我的问题是,有没有办法解开或别名导出的符号,这样我就不必在我的 dlsym 调用中使用像 Z19registerGrindPluginPN5Grind13PluginManagerE 这样的怪物?
我确实看到了一些关于 -alias_list 作为链接器选项的信息,但我还没有完全弄清楚如何在 Xcode 中使用它。如果这是解决方案,有人可以提供有关如何使用它的更多详细信息吗?

最佳答案

从长远来看,您尝试这样做的方式不会奏效。

您不能指望任何特定的 C++ 修饰/去修饰算法。不同的编译器——甚至同一编译器的不同版本——使用了不同的编译器。因此,您可以这样做,并切换到新版本的 Xcode,然后陷入糟糕的境地。

此外,C++ 还受到 Fragile Binary Interface Problem 的影响。 .为了避免这种情况,Grind::PluginManager 实例内部的所有操作,从创建到成员访问到删除,都需要在同一个动态库中进行。

解决这些问题是 Objective C 的消息传递系统和 Windows OLE 系统背后的一些基本原理。

C++ 解决方案是使用包装系统。

首先,您需要定义一个不透明的指针类型来代替 Grind::PluginManager*。 C 语言 Cocoa 绑定(bind)做了很多这样的事情。

typedef void* MyGrindPlugInManagerOpaqueHandle;

其次,对于您想要从动态库外部对 Grind::PluginManager 执行的每个操作,您需要使用 extern "C"定义一个具有未损坏的 C 绑定(bind)的函数,并将这些不透明指针之一作为参数。例如:
#ifdef __cplusplus
extern "C" {
#endif

void foo_wrapper(MyGrindPlugInManagerOpaqueHandle *bar);

#ifdef __cplusplus
}
#endif

第三,C++ 文件中的实现如下所示:
void foo_wrapper(MyGrindPlugInManagerOpaqueHandle *bar)
{
Grind::PluginManager* baz = (Grind::PluginManager*)bar;
baz->foo();
}

关于xcode - 如何在 macOS 上的 Xcode 中的动态库中从 C++ 中解开导出的符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4506487/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com