linux下so编写 - 动态库-类
发布日期:2021-10-10 05:31:25
浏览次数:33
分类:技术文章
本文共 2451 字,大约阅读时间需要 8 分钟。
linux下so编写 - 动态库-类
文章目录
引言
加载类有点困难,因为我们需要类的一个实例,而不仅仅是一个函数指针。我们无法通过new来创建类的实例,因为类是在动态库中定义的而不是在可执行程序中定义的,况且有时候我们连动态库中具体的类的名字都不知道。
解决方案是:利用多态性!我们在可执行文件中定义一个带虚成员函数的接口基类,而在模块中定义派生实现类。通常来说,接口类是抽象的(如果一个类含有虚函数,那它就是抽象的)。因为动态加载类往往用于实现插件,这意味着必须提供一个清晰定义的接口──我们将定义一个接口类和派生实现类。
接下来,在模块中,我们会定义两个附加的类工厂函数(class factory functions)(或称对象工厂函数)。其中一个函数创建一个类实例,并返回其指针;另一个函数则用以销毁该指针。这两个函数都以extern "C"来限定修饰。
代码
- testso.h
/********************************************************************************** * 最上层的接口:c接口用于创建父类、销毁父类 * 父类:用于c函数的调用创建与销毁 * 子类:真正使用的 * 调用完毕 **********************************************************************************/#ifndef _TESTSO_H_#define _TESTSO_H_// 只能通过基类调用,因此需要先定义一个基类,然后在create中生成真正需要生成的对象。class CBase{public: CBase() {}; ~CBase() {};public: int a, b; virtual int add(void) = 0;};class Base : public CBase{public: Base() {}; ~Base() {};public: virtual int add(void) { return -1; }};class A : public Base{public: A() {}; ~A() {};public: int c;public: int add(void);};typedef CBase* create_t(void); // create factorytypedef void destory_t(CBase*); // destory#endif // _TESTSO_H_
- testso.cpp
#include "testso.h"int A::add(void){ return a + b;}extern "C"{ CBase* create(void) // 注意:create函数必须返回Base的对象,不能直接返回A的对象,否则后面调用A::add()的时候会提示错误。 { return new A; } void destory(CBase *p) { if (p) delete p; }}
- main.cpp
#include#include #include #include #include "testso.h"void print_usage(void){ printf("Usage: myso SO_PATH/n");}int main(int argc, char *argv[]){ if (2 != argc) { print_usage(); exit(0); } const char *soname = argv[1]; void *so_handle = dlopen(soname, RTLD_LAZY); if (!so_handle) { fprintf(stderr, "Error: load so `%s' failed.\n", soname); exit(-1); } dlerror(); create_t *create = (create_t*) dlsym(so_handle, "create"); char *err = dlerror(); if (NULL != err) { fprintf(stderr, "%s\n", err); exit(-1); } CBase *pa = create(); pa->a = 57; pa->b = 3; //pa->c = 4; printf("A.add(57, 3)=%d\n", pa->add()); // 注意,这里通过虚函数实现了 // 对A::add()的调用。 destory_t *destory = (destory_t*) dlsym(so_handle, "destory"); err = dlerror(); if (NULL != err) { fprintf(stderr, "%s\n", err); exit(-1); } destory(pa); pa = NULL; dlclose(so_handle); printf("DONE!\n"); return 0;}
转载地址:https://blog.csdn.net/qq_22054285/article/details/87195364 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年03月24日 14时49分09秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Redis6.0配置文件详解
2019-04-26
Redis(二)Redis持久化(RDB+AOF)详解
2019-04-26
【JVM】一文了解双亲委派机制及其作用
2019-04-26
一文读懂JWT+JAVA的两种实现方式
2019-04-26
Java 对HashMap 进行排序的几种场景
2019-04-26
MySQL索引优化总结以及索引失效常见问题
2019-04-26
MySQL批量插入数据(load data 和存储过程方式)
2019-04-26
MySQL 表锁、行锁、间隙锁、页锁介绍分析
2019-04-26
codeforces 789A(数学)
2019-04-26
Codeforces 796A
2019-04-26
dp46上 HDU2084
2019-04-26
dp46上 HDU1421
2019-04-26
UESTC 1324线段树
2019-04-26
POJ1651 区间dp
2019-04-26
spfa、Dijkstra、Floyd算法最短路算法详解
2021-06-29
HDU4725(spfa+双端队列优化)
2021-06-29
PowerOj 2392(树状数组 or CDQ分治)
2021-06-29
HDU 6119(区间交叉问题)
2021-06-29
hdu 6143(精妙的递推)
2021-06-29