动态库的多重链库方法

动态库的多重链库方法

因项目需要将c++接口进行封装成c接口调用,实现可执行文件(a.out)去链接b.so(封装的c接口),并且b.so依赖于c.so(c++接口)。

方法一:a.out隐式加载b.so,b.so隐式加载c.so;

源代码:

//cplus.cc  记为c++接口的源文件,编译生成libcplus.so

//g++ cplus.cc -o libcplus.so -shared -fPIC

#include <iostream>

int cplusfunc(std::string str, int n) {
    std::cout << "str:" << str << std::endl;
    std::cout << "n:" << n << std::endl;
    return 0;
}
//cplus.h

#ifndef _CPLUS_H_

#define _CPLUS_H_

#include <iostream>

int cplusfunc(std::string str, int n);

#endif // _CPLUS_H_
//c.cc

//g++ c.cc -o libccc.so -shared -fPIC编译生成libccc.so

//注意了,此处不需要去链接libcplus.so,因为编译生成动态库时,编译器只关心本文件的函数实现,不会去关心

//函数内部调用的其他函数的实现,只需要保证其他函数的声明都能找到就行

#include "c.h"

#include "cplus.h"

#include<iostream>

int cfunc(char* ch, int n) {
    std::string s = ch;
    //此处调用c++接口库
    cplusfunc(s, n);
}


//c.h

#ifndef _C_H_

#define _C_H_

extern "C"{
    int cfunc(char* ch, int n);
}

#endif
//main.cc

//g++ main.cc -L./ -lccc -lcplus

//编译main函数的时候指定链接libccc.so与libcplus.so

#include <iostream>

//调用c.h头文件

#include "c.h"

int main() {

std::string s = "zheng";
char* ch =const_cast<char*>( s.c_str());
int k = 7;
cfunc(ch, k);
return 0;

}

方法二:a.out显示加载b.so,b.so隐式加载c.so;

这里对于cplus.h cplus.cc c.h c.cc几个文件都是一样的,唯一的区别就是main函数需要改成显示调用libccc.so

源代码:

//cplus.cc  记为c++接口的源文件,编译生成libcplus.so

//g++ cplus.cc -o libcplus.so -shared -fPIC

#include <iostream>

int cplusfunc(std::string str, int n) {
    std::cout << "str:" << str << std::endl;
    std::cout << "n:" << n << std::endl;
    return 0;
}


//cplus.h

#ifndef _CPLUS_H_

#define _CPLUS_H_

#include <iostream>

int cplusfunc(std::string str, int n);

#endif // _CPLUS_H_
//c.cc

//g++ c.cc -o libccc.so -shared -fPIC编译生成libccc.so

//注意了,此处不需要去链接libcplus.so,因为编译生成动态库时,编译器只关心本文件的函数实现,不会去关心

//函数内部调用的其他函数的实现,只需要保证其他函数的声明都能找到就行

#include "c.h"

#include "cplus.h"

#include<iostream>

int cfunc(char* ch, int n) {
    std::string s = ch;
    //此处调用c++接口库
    cplusfunc(s, n);
}
//这里使用extern "C"是方便main函数显示调用的时候不用考虑g++编译器改变函数名

//c.h

#ifndef _C_H_

#define _C_H_

extern "C"{
    int cfunc(char* ch, int n);
}

#endif
//main.cc

//编译main函数的时候,因为libccc.so是显示加载调用的,所以编译的时候根本不用关心有没有libccc.so的存在,只需要在编译的时候加上-ldl即可。但是因为libccc.so又是隐式加载libcplus.so的,所以在编译main函数的时候,必须加上-lcplus,避免再main函数运行的时候找不到c++接口(cplusfunc)的实现。

// g++ main.cc -ldl -L./ -lcplus

#include <iostream>

#include "dlfcn.h"

typedef int(*Fun)(char*, int);

int main() {

void* handle;
Fun fun = NULL;
char* error;
handle = dlopen("./libccc.so", RTLD_LAZY);
if (!handle) {
    std::cout << "error" << std::endl;
    return 0;
}
dlerror();
fun = (Fun)dlsym(handle, "cfunc");
if ((error = dlerror()) != NULL) {
    std::cout << "error" << error << std::endl;
    return 0;
}
std::string s = "zheng";
char* ch = const_cast<char*>(s.c_str());
int k = 7;
fun(ch, k);

return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值