资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

c语言使用so文件的函数 c++生成so

请问我有一个.so文件,如何在Linux下编程使用呢?

-lxx

员工经过长期磨合与沉淀,具备了协作精神,得以通过团队的力量开发出优质的产品。成都创新互联坚持“专注、创新、易用”的产品理念,因为“专注所以专业、创新互联网站所以易用所以简单”。公司专注于为企业提供网站设计、做网站、微信公众号开发、电商网站开发,成都小程序开发,软件按需求定制开发等一站式互联网企业服务。

xx是你的.so文件名

其实使用方法和你使用数学库函数是一样的,源代码中添加

#include math.h,编译的时候,加上-lm参数。

注:linux下的.so文件为共享库,相当于windows下的dll文件。

扩展资料: 

linux下编写调用so文件实例

.so是Linux(Unix)下的动态链接库. 和.dll类似.

比如:

文件有: a.c, b.c, c.c

gcc -c a.c

gcc -c b.c

gcc -c c.c

gcc -shared libXXX.so a.o b.o c.o

要使用的话也很简单. 比如编译d.c, 使用到libXXX.so中的函数, libXXX.so地址是MYPATH 

gcc d.c -o d -LMYPATH -lXXX

注意不是-llibXXX

test.c文件和一个test.h,这两个文件要生成libsotest.so文件。然后我还有一个testso.c文件,在这个文件里面调用libsotest.so中的函数。

编写的过程中,首先是编译so文件,我没有编写makefile文件,而是参考的2里面说的直接写的gcc命令。

因为so文件里面没有main函数,所以是不可执行的,所以编译的时候要加上-c,只生成目标文件。

怎样动态调用.so文件中的类方法

相关接口:

#include dlfcn.hvoid *dlopen(const char *filename, int flag);char *dlerror(void);void *dlsym(void *handle, const char *symbol);int dlclose(void *handle);123456789

eg:

dlapi.c

/*

[root@localhost eg]# gcc main.c -Wl,-rpath=./ -ldl -D_TEST

[root@localhost eg]# g++ main.c -Wl,-rpath=./ -ldl -D_TEST

*/#include stdio.h#include stdlib.h#include unistd.h#include dlfcn.h#ifdef __cplusplusextern "C" {#endiftypedef int (*PCall_func0)();typedef int (*PCall_func1)(void *);typedef int (*PCall_func2)(void *, void *);typedef int (*PCall_func3)(void *, void *, void *);typedef int (*PCall_func4)(void *, void *, void *, void *);int dynamic_call_library_func0(char *libName, char *funcName)

{

void *handle; void *error;

PCall_func0 selffunc=NULL; int ret; if(libName == NULL)return -9000; if(funcName == NULL)return -9001; //打开动态链接库

handle = dlopen(libName, RTLD_LAZY); if (!handle) { printf("%s\n", dlerror()); return -9000;

}

dlerror(); //获取一个函数

selffunc = (PCall_func0)dlsym(handle, funcName); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); return -9001;

}

ret = selffunc(); //dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

dlclose(handle); return ret;

}int dynamic_call_library_func1(char *libName, char *funcName, void *argv1)

{

void *handle; void *error;

PCall_func1 selffunc=NULL; int ret; if(libName == NULL)return -9000; if(funcName == NULL)return -9001; //打开动态链接库

handle = dlopen(libName, RTLD_LAZY); if (!handle) { printf("%s\n", dlerror()); return -9000;

}

dlerror(); //获取一个函数

selffunc = (PCall_func1)dlsym(handle, funcName); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); return -9001;

}

ret = selffunc(argv1); //dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

dlclose(handle); return ret;

}int dynamic_call_library_func2(char *libName, char *funcName, void *argv1, void *argv2)

{

void *handle; void *error;

PCall_func2 selffunc=NULL; int ret; if(libName == NULL)return -9000; if(funcName == NULL)return -9001; //打开动态链接库

handle = dlopen(libName, RTLD_LAZY); if (!handle) { printf("%s\n", dlerror()); return -9000;

}

dlerror(); //获取一个函数

selffunc = (PCall_func2)dlsym(handle, funcName); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); return -9001;

}

ret = selffunc(argv1, argv2); //dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

dlclose(handle); return ret;

}int dynamic_call_library_func3(char *libName, char *funcName, void *argv1, void *argv2, void *argv3)

{

void *handle; void *error;

PCall_func3 selffunc=NULL; int ret; if(libName == NULL)return -9000; if(funcName == NULL)return -9001; //打开动态链接库

handle = dlopen(libName, RTLD_LAZY); if (!handle) { printf("%s\n", dlerror()); return -9000;

}

dlerror(); //获取一个函数

selffunc = (PCall_func3)dlsym(handle, funcName); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); return -9001;

}

ret = selffunc(argv1, argv2, argv3); //dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

dlclose(handle); return ret;

}int dynamic_call_library_func4(char *libName, char *funcName, void *argv1, void *argv2, void *argv3, void *argv4)

{

void *handle; void *error;

PCall_func4 selffunc=NULL; int ret; if(libName == NULL)return -9000; if(funcName == NULL)return -9001; //打开动态链接库

handle = dlopen(libName, RTLD_LAZY); if (!handle) { printf("%s\n", dlerror()); return -9000;

}

dlerror(); //获取一个函数

selffunc = (PCall_func4)dlsym(handle, funcName); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); return -9001;

}

ret = selffunc(argv1, argv2, argv3, argv4); //dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

dlclose(handle); return ret;

}#ifdef _TESTint main(int rgvs, char **rgva)

{char buff[]="asdfasdf";int x=8;printf("main gcc build\n");printf("g_path gcc libeggcc.so char *\n");

dynamic_call_library_func1("/home/workspace/eg/libeggcc.so", "show1", buff);printf("g_path g++ libegg++.so char *\n");

dynamic_call_library_func1("/home/workspace/eg/libegg++.so", "show1", buff);printf("../lib path gcc libeggcc.so char *\n");

dynamic_call_library_func1("libeggcc.so", "show1", buff);printf("../lib path g++ libegg++.so char *\n");

dynamic_call_library_func1("libegg++.so", "show1", buff);printf("g_path gcc libeggcc.so int\n");

dynamic_call_library_func1("/home/workspace/eg/libeggcc.so", "show2", x);printf("g_path g++ libegg++.so int\n");

dynamic_call_library_func1("/home/workspace/eg/libegg++.so", "show2", x);printf("../lib path gcc libeggcc.so int\n");

dynamic_call_library_func1("libeggcc.so", "show2", x);printf("../lib path g++ libegg++.so int\n");

dynamic_call_library_func1("libegg++.so", "show2", x); return 0;

}#endif#ifdef __cplusplus}#endif123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222

dlapi.h

#ifndef _DL_API_H#define _DL_API_H#ifdef __cplusplusextern "C" {#endif/*

使用g++编译的.so库中,函数前必须添加 exter "C"

函数参数类型为指针,不或以为引用

*/int dynamic_call_library_func0(char *libName, char *funcName) ;int dynamic_call_library_func1(char *libName, char *funcName, void *argv1) ;int dynamic_call_library_func2(char *libName, char *funcName, void *argv1, void *argv2) ;int dynamic_call_library_func3(char *libName, char *funcName, void *argv1, void *argv2, void *argv3) ;int dynamic_call_library_func4(char *libName, char *funcName, void *argv1, void *argv2, void *argv3, void *argv4) ;#ifdef __cplusplus}#endif#endif1234567891011121314151617181920212223242526

eg.c

/*

[root@localhost eg]# gcc eg.c -fPIC -shared -o libeggcc.so[root@localhost eg]# g++ eg.c -fPIC -shared -o libegg++.so*/#include stdio.h#include stdlib.h#include string.h#include unistd.h#include sys/socket.h#include netinet/in.h#include arpa/inet.hint show1(char *src)

{ printf("%s\n", src); return 100;

}int show2(int *x)

{ printf("%2d\n", *x); return 101;

}12345678910111213141516171819202122232425262728293031

eg.cpp

/*

[root@localhost eg]# gcc eg.c -fPIC -shared -o libeggcc.so

[root@localhost eg]# g++ eg.c -fPIC -shared -o libegg++.so

*/#include stdio.h#include stdlib.h#include string.h#include unistd.h#include sys/socket.h#include netinet/in.h#include arpa/inet.hextern "C" int show1(char *src)

{ printf("%s\n", src); return 100;

}extern "C" int show2(int *x)

{ printf("%2d\n", *x); return 101;

}12345678910111213141516171819202122232425262728293031

main.c

/*

[root@localhost eg]# gcc main.c -Wl,-rpath=./ -ldl -D_TEST

[root@localhost eg]# g++ main.c -Wl,-rpath=./ -ldl -D_TEST

*/#include stdio.h#include stdlib.h#include unistd.h#include dlfcn.h#include "dlapi.h"int main(int rgvs, char **rgva)

{char buff[]="asdfasdf";int x=8;int ret;printf("main gcc build\n");printf("\ng_path gcc libeggcc.so char *\n");

ret = dynamic_call_library_func1("/home/workspace/eg/libeggcc.so", "show1", buff);printf("\ng_path g++ libegg++.so char *\n");

dynamic_call_library_func1("/home/workspace/eg/libegg++.so", "show1", buff);printf("\ncur lib path gcc libeggcc.so char *\n");

dynamic_call_library_func1("libeggcc.so", "show1", buff);printf("\ncur lib path g++ libegg++.so char *\n");

dynamic_call_library_func1("libegg++.so", "show1", buff);printf("\ng_path gcc libeggcc.so int\n");

dynamic_call_library_func1("/home/workspace/eg/libeggcc.so", "show2", x);printf("\ng_path g++ libegg++.so int\n");

dynamic_call_library_func1("/home/workspace/eg/libegg++.so", "show2", x);printf("\ncur lib path gcc libeggcc.so int\n");

dynamic_call_library_func1("libeggcc.so", "show2", x);printf("\ncur path g++ libegg++.so int\n");

dynamic_call_library_func1("libegg++.so", "show2", x); return 0;

}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950

makefile

all:

gcc eg.c -fPIC -shared -o libeggcc.so

g++ eg.cpp -fPIC -shared -o libegg++.so

gcc dlapi.c -ldl -fPIC -shared -o libdlapi.so

g++ main.c -L. -ldlapi -Wl,-rpath=./ -Wl,-rpath=./lib

123456

引用:

百度 dlopen(3) - Linux man page

错误:

未找到符合

该函数的定义没有链接进.so文件中时,在链接时加上-Wl,-z -Wl,defs参数,可以避免这个问题

linux下如何用c++编译so文件,c语言又怎样调用这个so文件

根据相应的头文件、和链接使用的库文件,编译链接后,即是可以使用该.so文件了

~~~~~~~

Linux c++开发.so文件的使用

假设在linux上用gcc编译程序,需要用下列编译选项生成.so文件:

gcc -fPIC -shared

.so 文件安装一般是在/usr/lib或者/usr/local/lib下,安装后不需要绝对路径即可使用。当然你也可以安装到工程文件夹下面,不过很少有这么做的。使用时只需要dlopen()函数打开这个库,用dlsym()函数将动态库的函数体加载进来;同样已加载的动态函数库可以用dlclose()关闭。

详细使用方法百度搜dlopen 即可。

linux的C编程,怎么使用so文件

linux下的.so文件为共享库,相当于windows下的dll文件,使用方法如下:

在你的工程源代码里包含.h头文件,然后可以调用动态库里的函数,在链接的时候加上如下编译器参数:

-l xx.so

如果你的so文件是以lib开头的,还可以直接这样使用:

-lxx

xx是你的.so文件名

其实使用方法和你使用数学库函数是一样的,源代码中添加

#include math.h,编译的时候,加上-lm参数。

linux下如何用c++编译so文件,c语言又怎样调用这个so文件

C++编译so文件与C编译so一样都是加参数 -shared

C语言调用C++的so

首先C要调用的C++的函数必须是extern "C"声明的。

其次编译C程序时需要增加链接libstdc++.so(可能名字不打对自己查查)


本文名称:c语言使用so文件的函数 c++生成so
文章起源:http://cdkjz.cn/article/hghehs.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220