代码之家  ›  专栏  ›  技术社区  ›  DeepDeadpool

如何在C库的实现文件中使用C++ STL容器?

  •  9
  • DeepDeadpool  · 技术社区  · 7 年前

    假设我希望使用C++ STL容器来实现一个库,我希望C程序链接到…

    /* mynums.h */
    #ifndef MY_NUMS
    #define MY_NUMS
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void append_num(int num);
    void print_nums();
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    

    我的示例实现文件是

    /* mynums.cpp */
    #include "mynums.h"
    #include <vector>
    
    using std::vector;
    
    vector<int> nums;
    
    void append_num(int num)
    {
        nums.push_back(num);
    }
    
    void print_nums()
    {
        for (int i = 0; i < nums.size(); i++)
        {
            printf("%d, ", nums[i]);
        }
        printf("\n");
    }
    

    我的应用程序看起来像

    /* app.c */
    #include "mynums.h"
    
    int main()
    {
        append_num(1);
        append_num(2);
        append_num(3);
        print_nums();
    
        return 0;
    }
    

    我编译这些的命令是

    # Compiles and runs
    g++ -c -fpic -shared -std=c++0x -o libmynums.so mynums.cpp
    g++ -L. -lmynums -o app app.c
    
    # Library compiles, but the application fails
    g++ -c -fpic -shared -std=c++0x -o libmynums.so mynums.cpp
    gcc -L. -lmynums -o app app.c
    

    当我尝试第二组编译命令时,得到的错误是那些我们非常熟悉的非常长的STL错误。一个例子是

    ./libmynums.so" In function 'void std:vector<int, std::allocator<int> >::_M_emplace_back_aux<int const&>(int const &)':
    mynums.cpp:(.text._ZNSt6vectorIiSaIiEE19_M_emplace_back_auxIIRKiEEEvDpOT_[_ZNSt6vectorIiSaIiEE19_M_emplace_back_auxIIRKiEEEvDpOT_]+0x15d): undefined reference to '__cxa-begin_catch'
    

    我希望能够使用gcc编译示例应用程序代码并将其链接到共享对象库。这有可能吗?如果是,那么对我提供的代码/命令需要做哪些更改?

    1 回复  |  直到 7 年前
        1
  •  8
  •   dbush    7 年前

    问题是您实际上没有创建共享库。您正在创建一个对象文件,并将其命名为一个共享库。

    这个 -c gcc/g++的选项意味着只执行编译阶段。这导致 libmynums.so 是一个对象文件。这就是为什么你可以通过g++而不是gcc链接到它。

    删除 -C 编译时的选项 mynums.cpp 你会得到一个共享的图书馆。