linux下c++动态库的生成及使用

摘要:
Linux下的动态链接库叫so,即SharedObject,共享对象。一些函数就不说了,网上多的是。把我遇到的问题写下来吧提示错误undefinedreferenceto`dlopen'编译时增加“-ldl”选项即可解决。提示错误cannotopensharedobjectfile:Nosuchfileordirectory将当前目录的绝对路径添加到LD_LIBRARY_PATH即可exportLD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/zhj/test_so/提示错误undefinedreferenceto检查了一下,原来在makefile里少包含了一个文件。这一类错误一般都是缺少相应的类文件所致。

文章来源于:http://hi.baidu.com/ablenavy/item/b498901c6826bbf587ad4e33

我的程序是一个类,在网上找了半天,都是c的例子,c++的类封装成静态库倒容易,可是如何封装成动态库,在其它程序中调用呢?
Linux下的动态链接库叫so,即Shared Object,共享对象。一些函数就不说了,网上多的是。把我遇到的问题写下来吧

提示错误 undefined reference to `dlopen'
编译时增加“-ldl”选项即可解决。

提示错误 cannot open shared object file: No such file or directory
将当前目录的绝对路径添加到LD_LIBRARY_PATH即可
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/zhj/test_so/

提示错误 undefined reference to
检查了一下,原来在makefile里少包含了一个文件。
这一类错误一般都是缺少相应的类文件所致。

例子来源:
http://www.linuxsir.org/bbs/printthread.php?t=266890

这个扩展名为hpp的文件,我分解了一下,下面就上代码吧

polygon.h
//----------
//polygon.h:
//----------
#ifndef POLYGON_H
#define POLYGON_H
#include <stdio.h>

class polygon {
protected:
double side_length_;

public:
polygon();
virtual ~polygon();

void set_side_length(double side_length);

virtual double area() const;
};

// the types of the class factories
typedef polygon* create_t();
typedef void destroy_t(polygon*);

#endif

polygon.cpp
//----------
//polygon.cpp:
//----------
#include "polygon.h"

polygon::polygon()
{
//set_side_length(0);
}

polygon::~polygon()
{
}

void polygon::set_side_length(double side_length)
{
printf("polygon side_length: %f ",side_length);
side_length_ = side_length;
printf("polygon side_length_: %f ",side_length_);
}

double polygon::area() const
{
return 0;
}

triangle.cpp
//----------
//triangle.cpp:
//----------
#include "polygon.h"
#include <cmath>

class triangle : public polygon {
public:
virtual double area() const {
printf("triangle side_length_: %f ",side_length_);
return side_length_ * side_length_ * sqrt(3) / 2;
}
};

// the class factories
extern "C" polygon* create() {
return new triangle;
}

extern "C" void destroy(polygon* p) {
delete p;
}

main.cpp
//----------
//main.cpp:
//----------
#include "polygon.h"
#include <iostream>
#include <dlfcn.h>

int main() {
using std::cout;
using std::cerr;

// load the triangle library
void* triangle = dlopen("./triangle.so", RTLD_LAZY);
if (!triangle) {
cerr << "Cannot load library: " << dlerror() << ' ';
return 1;
}

// reset errors
dlerror();

// load the symbols
create_t* create_triangle = (create_t*) dlsym(triangle, "create");
const char* dlsym_error = dlerror();
if (dlsym_error) {
cerr << "Cannot load symbol create: " << dlsym_error << ' ';
return 1;
}

destroy_t* destroy_triangle = (destroy_t*) dlsym(triangle, "destroy");
dlsym_error = dlerror();
if (dlsym_error) {
cerr << "Cannot load symbol destroy: " << dlsym_error << ' ';
return 1;
}

// create an instance of the class
polygon* poly = create_triangle();

// use the class
poly->set_side_length(7);
cout << "The area is: " << poly->area() << ' ';

// destroy the class
destroy_triangle(poly);

// unload the triangle library
dlclose(triangle);
}

makefile

objects = main.o polygon.o
main: $(objects)
g++ -g -rdynamic -o $@ $(objects) -ldl
main.o: main.cpp
g++ -g -c main.cpp
polygon.o: polygon.cpp polygon.h
g++ -g -c polygon.cpp

.PHONY : clean
clean :
-rm main $(objects)

用下面的命令编译,生成libtriangle.so
g++ -g -fpic -shared -o libtriangle.so triangle.cpp polygon.cpp

然后make一下,运行main试试吧!

免责声明:文章转载自《linux下c++动态库的生成及使用》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇05-函数式编程Python排列组合下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

ROS node调用service: ros::service::call/client.call()

简介:介绍如何在一个node里调用现有的rosservice list查询到的service。 效果:通过talker publish需要调用服务的数据,listener接收到数据后调用服务进行三个整形数据相加,并返回相加和。 环境:ubuntu 14.04 +indigo. 备注:文中未详细介绍的api或ros的基本函数请参看之前博文。 [正文] 创建过...

【web端权限维持】利用ADS隐藏webshell

0X01 前言   未知攻,焉知防,在web端如何做手脚维护自己拿到的权限呢?首先要面临的是webshell查杀,那么通过利用ADS隐藏webshell,不失为一个好办法。 0X02 利用ADS隐藏webshell   关于ADS的介绍,就不再阐述,详见尾部参考资料。   PHP 一句话木马:<?php @eval($_POST['chopper']...

Linux下的头文件搜索路径

对于以压缩包发布的软件,在它的目录下通常都有一个配置脚本configure,它的作用确定编译参数(比如头文件位置、连接库位置等),然后生成Makefile以编译程序。可以进入该软件的目录,执行"./configure --help"命令查看使用帮。 一个程序能正确编译、链接、运行需要满足3个条件:预处理时能找到头文件,连接时能找到库(静态库或动态库),运...

FreeMarker include指令(3.3)

可以使用include指令在模板中插入另外一个FreeMarker模板文件。 语法: <#include path/> or <#include path options /> 说明: path:要包含文件的路径。可以使用相对路径和绝对路径。通常使用/(斜杠)来分割路径成分。 支持的options有: encoding:算作是...

使用lua实现Spine动画的预加载

创建spine动画有两种方法,分别是createwithfile和createwithdata。 createWithFile是通过加载动作数据马上进行创建,如果spine动画中的json文件大小超过100k时,会出现卡顿现象,如果动画文件偏小,可以使用这个方法来创建动画。 createWithData是通过预加载,保存动画数据在spSkeletonDat...

vue中使用keepAlive(缓存页面&amp;amp;记忆上次浏览位置)及使用后生命周期的改变

以下部分内容转自博客(另外配有自己见解):https://www.cnblogs.com/nokelong/p/8116631.html 使用keepAlive缓存页面,一可以减少服务器请求次数,二则可以在用户返回上一页后记忆到上次浏览位置(ios端微信浏览器不适用,不兼容,需要另行配置:见例子(1)) keep-alive的介绍如下: 1,把切换出去的组...