c++ - 从 Objective-C 链接 C++ 库 (libtorrent)

标签 c++ objective-c xcode linker-errors mixing

我尝试使用 Xcode 5.0 Objective-C 项目中的 libtorrent 库,但没有成功。

我已经使用 LLVM 5.0 从源构建了 boost 1.54 和 libtorrent-rasterbar(最新),没有任何问题。另外,通过 MacPorts,我获得了 pkg-config 来获取 libtorrent-rasterbar 库的正确 cflags。根据我的build设置,pkgconfig 库和 cflags 的输出为:

      -DTORRENT_USE_OPENSSL -DWITH_SHIPPED_GEOIP_H 
-DBOOST_ASIO_HASH_MAP_BUCKETS=1021 
    -DBOOST_EXCEPTION_DISABLE -DBOOST_ASIO_ENABLE_CANCELIO 
    -DBOOST_ASIO_DYN_LINK -DTORRENT_LINKING_SHARED -I/usr/local/include 
    -I/usr/local/include/libtorrent 

    -L/usr/local/lib -ltorrent-rasterbar 

当然,我将这些参数添加到 Xcode“链接器标志”和“C/C++ 标志”设置中。

不幸的是,我无法让我调用的函数正确链接。这是我在 testclass.cpp 文件中编写的示例类:

#include "libtorrent/entry.hpp"
#include "libtorrent/bencode.hpp"
#include "libtorrent/torrent_info.hpp"
#include "libtorrent/file.hpp"
#include "libtorrent/storage.hpp"
#include "libtorrent/hasher.hpp"
#include "libtorrent/create_torrent.hpp"

void testclass::addFilesFromPath(const char* path)
{
    libtorrent::file_storage fs;
    libtorrent::add_files(fs, path);
}

尝试从 createpackage.mm 文件调用:

testclass* pPackage = new testclass();
testclass->addFilesFromPath([_sessionDir UTF8String]);

链接器找不到符号,输出为:

Undefined symbols for architecture x86_64:
"libtorrent::parent_path(std::__1::basic_string, std::__1::allocator > const&)", referenced from: libtorrent::add_files(libtorrent::file_storage&, std::__1::basic_string, std::__1::allocator > const&, unsigned int) in createpackage.o
"libtorrent::detail::add_files_impl(libtorrent::file_storage&, std::__1::basic_string, std::__1::allocator > const&, std::__1::basic_string, std::__1::allocator > const&, boost::function, std::__1::allocator >)>, unsigned int)", referenced from: libtorrent::add_files(libtorrent::file_storage&, std::__1::basic_string, std::__1::allocator > const&, unsigned int) in createpackage.o
"libtorrent::complete(std::__1::basic_string, std::__1::allocator > const&)", referenced from: libtorrent::add_files(libtorrent::file_storage&, std::__1::basic_string, std::__1::allocator > const&, unsigned int) in createpackage.o
"libtorrent::filename(std::__1::basic_string, std::__1::allocator > const&)", referenced from: libtorrent::add_files(libtorrent::file_storage&, std::__1::basic_string, std::__1::allocator > const&, unsigned int) in createpackage.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

我很困惑。检查 libtorrent-raster bar 架构是否为 x86_64。另外,boost 构建正常。我对这种 C++/Objetive-C 代码混合方法不熟悉。

谢谢。

编辑1:

我采用了最小样本。制作了以下CPP文件:

#include "libtorrent/file.hpp"
#include "libtorrent/storage.hpp"
#include "libtorrent/create_torrent.hpp"

int main()
{
    libtorrent::file_storage fs;
    libtorrent::add_files(fs, ".");
}

在命令行中,尝试过:

c++ test.cpp $(pkg-config /usr/local/lib/pkgconfig/libtorrent-rasterbar.pc --cflags --libs) -lboost_system

构建成功。所以我想知道如何将所有 pkg​​-config 数据放入 OSX 中正确的目标配置中。

最佳答案

问题终于解决了。

让我们检查符号,将生成的目标文件与 libtorrent 库中包含的符号进行比较。

nm createpackage.o|grep 'add_files'
                 U __ZN10libtorrent6detail14add_files_implERNS_12file_storageERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESB_N5boost8functionIFbS9_EEEj
00000000000002a0 S __ZN10libtorrent9add_filesERNS_12file_storageERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEj
00000000000018e0 S __ZN10libtorrent9add_filesERNS_12file_storageERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEj.eh

比较:

$ nm libtorrent-rasterbar.a | grep 'add_files'
00000000000002f0 T __ZN10libtorrent6detail14add_files_implERNS_12file_storageERKSsS4_N5boost8functionIFbSsEEEj
0000000000006e68 S __ZN10libtorrent6detail14add_files_implERNS_12file_storageERKSsS4_N5boost8functionIFbSsEEEj.eh

许多人可以想象看到该输出的差异,那就是我对 .mm 文件使用 LLVM 标准 C++ 库,而 libtorrent 是使用 GCC Stdlib 编译的,这就是引用 char_traits、basic_string 等的不同符号的原因.

因此,将 XCode Build Settings > Standard C++ Library 更改为 libstdc++ 解决了问题。

关于c++ - 从 Objective-C 链接 C++ 库 (libtorrent),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19020724/

相关文章:

C++ 11 范围基于带指针的语句

ios - objective-C 中的 "@TRUE"

objective-c - cmake - 设置 - xcode 属性 - 隐式链接 objective-c 运行时支持

xcode - swift 错误 : Cannot find an initializer for type 'Double' that accepts an argument list of type '(String)'

c++ - 如何在 log4cplus 中添加自定义过滤器?

c++ - 为什么控制面板的 PIDL 会有所不同?

python - 带有额外模块的 OpenCV 3.0.0 - imgproc 依赖

objective-c - 创建tableview后如何解决ios异常?

ios - 将方法添加到类别(来自 github)

ios - 在 Google map 中创建标记