分段错误和对“dlopen'”的未定义引用; 我尝试在C++中动态加载库。我遵循教程。 我的文件夹结构如下所示: ├── main.cpp ├── testLib.cpp ├── testLib.h ├── testLib.so └── testVir.h

分段错误和对“dlopen'”的未定义引用; 我尝试在C++中动态加载库。我遵循教程。 我的文件夹结构如下所示: ├── main.cpp ├── testLib.cpp ├── testLib.h ├── testLib.so └── testVir.h,c++,gcc,g++,shared-libraries,C++,Gcc,G++,Shared Libraries,main.cpp #include<iostream> #include<dlfcn.h> #include<stdio.h> #include "testVir.h" using namespace std; int main() { void *handle; handle = dlopen("./testLib.so", RTLD_NOW); if (!handle) { printf("The

main.cpp

#include<iostream>
#include<dlfcn.h>
#include<stdio.h>
#include "testVir.h"

using namespace std;

int main()
{
    void *handle;
    handle = dlopen("./testLib.so", RTLD_NOW);
    if (!handle)
    {
           printf("The error is %s", dlerror());
    }

    typedef TestVir* create_t();
    typedef void destroy_t(TestVir*);

    create_t* creat=(create_t*)dlsym(handle,"create");
    destroy_t* destroy=(destroy_t*)dlsym(handle,"destroy");
    if (!creat)
    {
           cout<<"The error is %s"<<dlerror();
    }
    if (!destroy)
    {
           cout<<"The error is %s"<<dlerror();
    }
    TestVir* tst = creat();
    tst->init();
    destroy(tst);
    return 0 ;
}
#include <iostream>
#include "testVir.h"
#include "testLib.h"

using namespace std;
void TestLib::init()
{
   cout<<"TestLib::init: Hello World!! "<<endl ;
}

//Define functions with C symbols (create/destroy TestLib instance).
extern "C" TestLib* create()
{
    return new TestLib;
}
extern "C" void destroy(TestLib* Tl)
{
   delete Tl ;
}
testVir.h

#ifndef TESTLIB_H
#define TESTLIB_H

class TestLib
{
 public:
     void init();
};

#endif
#ifndef TESTVIR_H
#define TESTVIR_H

class TestVir
{
public:
  virtual void init()=0;
};

#endif
我使用这个命令获取我的
testLib.so
g++-shared-fPIC testLib.cpp-o testLib.so
, 这很好,但是当我试图用
g++-ldl main.cpp-o test
我发现以下错误:

/tmp/ccFoBr2X.o: In function `main':
main.cpp:(.text+0x14): undefined reference to `dlopen'
main.cpp:(.text+0x24): undefined reference to `dlerror'
main.cpp:(.text+0x47): undefined reference to `dlsym'
main.cpp:(.text+0x5c): undefined reference to `dlsym'
main.cpp:(.text+0x6c): undefined reference to `dlerror'
main.cpp:(.text+0x95): undefined reference to `dlerror'
collect2: error: ld returned 1 exit status
G++版本(来自
G++--version
):
g++(Ubuntu 4.8.4-2ubuntu1~14.04.1)4.8.4

我不知道会发生什么,我需要一些资源来学习如何工作

编辑1 我通过使用这个命令编译我的main解决了这个问题。
g++main.cpp-ldl-o测试
。找到了这个补丁

但是现在,当我尝试运行
/test
时,我得到了
分段错误
。看起来 在这一行
tst->init()但指针看起来有效

编辑2 在接下来的教程中,我得到了相同的错误,
分段错误


如果你有很好的教程或文档,这将非常有帮助。

这与
dlopen
部分无关。您的
类TestLib
缺少来自
TestVir
的继承:

class TestLib : public TestVir
您还应该将
创建
/
销毁
签名修复为相同类型。因为您想隐藏
TestLib
类,所以应该返回并获取
TestVir*

extern "C" TestVir* create()
{
    return new TestLib();
}
extern "C" void destroy(TestVir* Tl)
{
   delete Tl ;
}
同时把函数类型放在标题中,否则你会在一段时间后击中自己的脚。为了让它发挥作用,你还必须


顺便说一句:您的错误处理缺少刷新,如果出现错误,您不应该继续操作。

这是有效的:static_cast(tst)->init()您需要将链接器标志移动到命令的末尾:
g++main.cpp-o test-ldl
另外,根据手册,在从
dlsym()赋值时,您应该将符号指针转换为(void**)
因为在某些系统上,直接转换可能会丢失位。参见mnual中的示例:它们确实
*(void**)(&create)=dlsym(句柄,“create”)你有任何我能阅读的文档,或者关于这个主题的教程?谢谢你的帮助。@ Mati我想这本书的有效C++,项目7是一个很好的起点。根据你的C++知识,一本基本的书,如《C++编程语言,第四版》可能对你有帮助。与动态库加载和C++的结合既不常见,也不特别优雅(不幸的是),但是如果您对语言本身更精通, DLOPEN/COMPUTE部分并不那么复杂。@ Matei也有,但我没有个人经验。
class TestVir
{
public:
    virtual void init()=0;
    virtual ~TestVir() = default; // note: C++11
};