代码之家  ›  专栏  ›  技术社区  ›  Ronny Brendel

利用C++实现动态链接

  •  1
  • Ronny Brendel  · 技术社区  · 16 年前

    运行整个事件将导致以下错误:

    Cannot open library "./libexamplefilter.so" ./libexamplefilter.so: undefined symbol: _ZTI10BaseFilter
    

    因为代码非常小并且可以理解,所以您应该能够立即理解它。 有人知道怎么回事吗?

    我是否应该将create()声明为extern“c”void*create(void); 然后抛出空指针,而不是直接尝试连接C++符号?

    下一步

    使用后 -Wl,-export-dynamic 它告诉我:

    Cannot load library symbols "./libexamplefilter.so" ./libexamplefilter.so: undefined symbol: create
    

    呃,我必须给一个被损坏的C++名字而不是“dLSym(句柄,”创建”)。可能。有优雅的方法吗?

    答案是声明create()extern“c”…创造… 这个很好用。 问题解决了。谢谢你的帮助和耐心。

    5 回复  |  直到 16 年前
        1
  •  4
  •   Employed Russian    16 年前

    编译主可执行文件时,需要使用链接器选项“export dynamic”。

    通常,主可执行文件不会导出其符号供动态链接器使用(除非该符号由参与链接的共享库使用),这意味着如果您的库回调到主exe,它将无法加载。

    当您尝试用虚拟方法对类进行子类化时,以及在某些其他情况下,这会隐式地发生。如果你想这么做,那就是失败。

    因此,当链接主程序时,添加 -Wl,-export-dynamic ,就行了。

        2
  •  1
  •   Harper Shelby damiankolasa    16 年前

    我在探索插件架构时遇到了这个问题。你的错误不在你的主站,而是你如何链接libexamplefilter.so。不幸的是,我没有代码(或者内存!)告诉你如何解决它,但是我 认为 您需要在一个单独的.so中声明basefilter类,并将libexamplefilter和您的应用程序链接起来。

        3
  •  1
  •   Troubadour    16 年前

    这可能是由于 _ZTI10BaseFilter 符号(这是类的类型信息)位于.so和应用程序之间。如果你跑步你会得到什么

    nm <target> | grep _ZTI10BaseFilter
    

    在每一个 target 包括basefilter,即动态库和可执行文件?

        4
  •  1
  •   Max Lybbert    16 年前

    我是否应该声明CREATE()作为Extn“C”Value*创建(空),然后抛出空指针,而不是直接尝试链接C++符号?

    我个人会推荐这个,即使这不是真正的问题。现在,在类似Unix的操作系统中,名称管理是相当标准的——Intel ABI和所有操作系统都是如此——但这并不是真正的标准,Windows使用了不同的名称管理方案(因此将应用程序移植到Windows需要更改这些字符串),我不确定OS X是否在运行中(因此移植到OS X可能需要更改这些字符串)。