从.so导入函数

时间:2017-12-15 12:37:48

标签: c++ boost dllimport

我需要从带有boost.dll库的Linux .so库中导入一个函数。我的代码是这样的:

namespace n1 {
    namespace n2 {
        struct st {
            std::string n;
            int m;
        }
    }
}

void foo(std::string const&, n1::n2::st& attr) {
    /*some implementation*/
}

在这里,我尝试导入函数foo()

int main(int argc, char** argv) {
    boost::filesystem::path path("some path");
    boost::dll::experimental::smart_library lib(path);
    auto f2 = lib.get_function<void(std::string const&, n1::n2::st&)>(path, "n1::n2::foo");  //<<----here runtime error
    f2( std::string(), st{});
}

但是我收到了这个运行时错误:

  

在抛出'boost :: exception_detail :: clone_impl&gt;'的实例后终止调用     what():boost :: dll :: shared_library :: get()失败(dlerror系统消息:/ path_to_my_library.so:未定义符号:n1 :: n2 :: foo):非法搜索

1 个答案:

答案 0 :(得分:2)

由于n1::n2::foo不是C兼容的导出名称,我建议您使用损坏的名称,或使用mangled_import

  

警告:此功能是实验性的

在我的编译器上

foo(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, n1::n2::st&)

到了

_Z3fooRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERN2n12n22stE

关于还导入结构的主题,请参阅Class Imports

更新

基于手动修剪方法的工作样本:

  1. shared.cpp

    #include "shared.h"
    #include <iostream>
    
    void foo(std::string const& msg, n1::n2::st& attr) {
        std::cout << msg << " from " << __FILE__ << ":" << __LINE__ << " (" << __PRETTY_FUNCTION__ << ")\n";
        std::cout << "attr.m = " << attr.m << "\n";
        std::cout << "attr.n = " << attr.n << "\n";
    }
    
  2. shared.h

    #include <string>
    namespace n1 { namespace n2 { struct st { std::string n; int m; }; } }
    
  3. 的main.cpp

    #include <boost/dll.hpp>
    #include <boost/dll/smart_library.hpp>
    #include <boost/dll/import_mangled.hpp>
    #include <boost/exception/diagnostic_information.hpp>
    #include <iostream>
    
    #include "shared.h"
    
    int main() {
        boost::filesystem::path path("./libshared.so");
        try {
            boost::dll::experimental::smart_library lib(path);
            //auto f1 = boost::dll::experimental::import_mangled<void(std::string const&, n1::n2::st&)>(path, "foo");
            auto f1 = boost::dll::import<void(std::string const&, n1::n2::st&)>(path, "_Z3fooRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERN2n12n22stE");
    
            n1::n2::st arg { "world", 42 };
            f1("hello", arg);
    
        } catch(boost::exception const& e) {
            std::cout << boost::diagnostic_information(e, true) << '\n';
        }
    }
    
  4. 查看 Live On Coliru

    编译:

    g++ -std=c++14 -shared -fPIC shared.cpp -o libshared.so
    g++ -std=c++14 main.cpp -ldl -lboost_system -lboost_filesystem
    

    使用

    显示损坏的名称
    nm libshared.so
    

    使用

    运行演示
    ./a.out
    

    打印

    hello from shared.cpp:5 (void foo(const string&, n1::n2::st&))
    attr.m = 42
    attr.n = world