【问题标题】:Using shared C++ library in Idris在 Idris 中使用共享 C++ 库
【发布时间】:2022-01-04 18:05:44
【问题描述】:

我想 FFI 到 Idris 的第三方 C++ 库,但我得到“未定义符号”。我是 C/C++ 编译新手。

我通过将 C++ 包装在我从 Idris 调用的纯 C 层中来做到这一点。 C++ 代码作为一组.h 标头和一个.so 共享库提供。目前我只有一个 C 文件,以后可能会有更多。

这是 C++ 库头文件 include/foo.h

#include <some/other/library/header.h>

namespace mynamespace {
  class Foo {
    public:
      Foo();
  }
}

和 C 包装器 wrapper.cpp

#include <foo.h>

extern "C" {
    struct cFoo;

    using namespace mynamespace;

    struct cFoo* cFoo_new() {
        return reinterpret_cast<cFoo*>(new Foo());
    }
}

共享库是 lib/libfoo_ext.so,我正在编译它们

g++ -shared -Iinclude -Llib -lfoo_ext -o libfoo.so wrapper.cpp

运行没有错误。同时,Idris 代码是

module Foo

import System.FFI

export
Foo : Type
Foo = Struct "cFoo" []

%foreign "C:cFoo_new,libfoo"
export
mkFoo : Foo

我正在测试文件中调用mkFoo。当我这样做时,我得到

Exception: (while loading libfoo.so) .../build/exec/_tmpchez_app/libfoo.so: undefined symbol: _ZN17mynamespace6FooC1Ev

【问题讨论】:

  • 构造函数的定义在哪里?
  • @molbdnilo Foo()的实际实现?也就是说,我想,在.so 中。这有意义吗?我会检查这个

标签: c++ c linker ffi idris


【解决方案1】:

这个命令:

g++ -shared -Iinclude -Llib -lfoo_ext -o libfoo.so wrapper.cpp

不正确。假设libfoo_ext 是实现mynamespace::Foo::Foo() 的第三方库,链接命令应该是:

g++ -shared -Iinclude -Llib -o libfoo.so wrapper.cpp -lfoo_ext 

链接行matters上的库和源的顺序,你的错了。

【讨论】:

  • 很好,谢谢。现在它显示了一个不同但更有希望的错误“异常:(加载 libfoo.so)libfoo_ext.so:无法打开共享对象文件:没有这样的文件或目录”。我会调查的
  • @joel 为此,您需要在与-Wl,-rpath=/path/to/lib 链接时正确(更好)设置RPATH,或在环境中设置LD_LIBRARY_PATH
  • LD_LIBRARY_PATH 工作。我会看看-rpath。在g++ 通话中会去哪里?
  • @joel 链接线上的任何地方。例如。 g++ -shared ... -lfoo_ext -Wl,-rpath=/path/to/directory/in/which/libfoo_ext.so/resides.
猜你喜欢
  • 2015-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-21
  • 2020-11-18
  • 2020-11-09
  • 1970-01-01
  • 2019-04-30
相关资源
最近更新 更多