现在的位置: 首页 > 综合 > 正文

c/c++基础(十七) 编译与加载 动态库(.so)

2019年09月12日 ⁄ 综合 ⁄ 共 1913字 ⁄ 字号 评论关闭

c文件filea.c:

#include <stdio.h>
void fun1()
{
	printf("i am from filea fun1 \n");
}


c文件fileb.c:

#include <stdio.h>
void fun2()
{
	printf("i am from fileb fun2 \n");
}


测试文件testso.c

void fun1();
void fun2();
int main(int argc,char *argv[])
{
	fun1();
	fun2();
	return 0;
}

1.将filea.c fileb.c编译成so库供testso.c调用,命令如下:


gcc -Wall -fpic -shared filea.c fileb.c -o first.so




2.编译testso.c并链接共享库first.so

gcc -Wall testso.c first.so -o testso




3.执行。

此时,执行./testso 将会抛出./testso: error while loading shared libraries: first.so:cannot open shared object file: No such file or directory

程序 testso已经完成,但要运行它必须让其能定位到共享库 first.so,因为库中的函数要在程序运行时被加载。 需要注意的是,当前工作目录可能不在共享库的查找路径中,因此需要使用如下的命令行设定环境变量LD_LIBRARY_PATH:


 $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./


再次执行./testso,输出正确结果:




4.通过代码加载so


CLoadSoFun.h文件:

#ifndef _CLOADSO_H
#define _CLOADSO_H

#ifdef _cplusplus
	extern "C" {
#endif

	void fun1();
	void fun2();

#ifdef _cplusplus
	}
#endif


#endif

CLoadSo.c文件:

#include <stdio.h>
#include <dlfcn.h>
#include "CLoadSoFun.h"

int main(int argc,char **argv)
{

	void *soHandle;
	int (*fun)();
	char *errorMsg;

	soHandle=dlopen("first.so",RTLD_LAZY);
	errorMsg=dlerror();


	printf("A1---------loadSo  is %s \n",soHandle ? "success" : "failed");
	if(errorMsg)
	{
		printf("A2--------loadSo error , Msg is: %s \n",errorMsg);
		return -1;
	}

	fun=dlsym(soHandle,"fun1");
	errorMsg=dlerror();
	printf("B1---------fun1 , fun1 is %s \n",fun ? "success" : "Null");
	if(fun)
	{
		fun();
	}
	if(errorMsg)
	{
		printf("B2---------fun1 error , Msg is: %s \n",errorMsg);
	}

	fun=dlsym(soHandle,"fun2");
	errorMsg=dlerror();
	printf("B3---------fun2 , fun2 is %s \n",fun ? "success" : "Null");
	if(fun)
	{
		fun();
	}
	if(errorMsg)
	{
		printf("B4---------fun2 error , Msg is: %s \n",errorMsg);
	}

	fun=dlsym(soHandle,"fun3");
	errorMsg=dlerror();
	printf("B5---------fun3 , fun3 is %s \n",fun ? "success": "Null");
	if(fun)
	{
		fun();
	}
	if(!errorMsg)
	{
		printf("B6---------fun3 error , Msg is: %s \n",errorMsg);
	}
	

	dlclose(soHandle);
	printf("C---------close LoadSo \n");

	return 0;
}

编译CLoadSo.c并且连接first.so文件

gcc -Wall CLoadSo.c -o CLoadSo -ldl 生成CLoadSo可执行文件

./CLoadSo 运行文件,执行结果如下:



参考文章:http://www.cnitblog.com/yunshichen/archive/2009/08/28/61065.html

抱歉!评论已关闭.