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