作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在尝试用 C++ 开发一个可以在应用程序中运行时加载的动态库。我终于让它工作了,但它有点难看。我有一个函数,它将指向 C++ 类的指针作为参数,如下所示:
bool registerGrindPlugin( Grind::PluginManager* mgr );
但当然它被导出为:
_Z19registerGrindPluginPN5Grind13PluginManagerE
我尝试了一个带有简单函数的 .c 文件,它导出为“registerGrindPlugin”,但当然我不能以这种方式将 C++ 类作为参数传递。
最佳答案
从长远来看,您尝试这样做的方式不会奏效。
您不能指望任何特定的 C++ 修饰/去修饰算法。不同的编译器——甚至同一编译器的不同版本——使用了不同的编译器。因此,您可以这样做,并切换到新版本的 Xcode,然后陷入糟糕的境地。
此外,C++ 还受到 Fragile Binary Interface Problem 的影响。 .为了避免这种情况,Grind::PluginManager 实例内部的所有操作,从创建到成员访问到删除,都需要在同一个动态库中进行。
解决这些问题是 Objective C 的消息传递系统和 Windows OLE 系统背后的一些基本原理。
C++ 解决方案是使用包装系统。
首先,您需要定义一个不透明的指针类型来代替 Grind::PluginManager*。 C 语言 Cocoa 绑定(bind)做了很多这样的事情。
typedef void* MyGrindPlugInManagerOpaqueHandle;
extern "C"
定义一个具有未损坏的 C 绑定(bind)的函数,并将这些不透明指针之一作为参数。例如:
#ifdef __cplusplus
extern "C" {
#endif
void foo_wrapper(MyGrindPlugInManagerOpaqueHandle *bar);
#ifdef __cplusplus
}
#endif
void foo_wrapper(MyGrindPlugInManagerOpaqueHandle *bar)
{
Grind::PluginManager* baz = (Grind::PluginManager*)bar;
baz->foo();
}
关于xcode - 如何在 macOS 上的 Xcode 中的动态库中从 C++ 中解开导出的符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4506487/
我是一名优秀的程序员,十分优秀!