linux函数库编写调用,补充:Linux动态库的编写与调用

1. 用 c 语言写动态库:

/*

* libsthc.h

* Declarations for function add

*/

#include "stdio.h"

#include "stdlib.h"

#include "stdarg.h"

#ifdef __cplusplus

extern "C"

{

#endif

int add(int x, int y);

#ifdef __cplusplus

}

#endif

/*

* libsthc.c

* Implementation of function add declared in libsthc.h

* in c language

*/

#include "libsthc.h"

int add(int x, int y)

{

return x + y;

}

#makefile

libsthc.so:libsthc.o

gcc -shared libsthc.o -lc -o libsthc.so

libsthc.o:libsthc.c libsthc.h

gcc -fPIC -c libsthc.c -o libsthc.o

all:libsthc.so

clean:

rm -f *.o *.so

make 完成后,会生成一个动态库,即 libsthc.so 。为了使其他程序也可以使用该动态库,需要将库文件 libsthc.so 拷贝到 /usr/lib 目录下 ( 由于权限的问题,一般要以 root 的身分进行拷贝 ) ,为了使其他程序也可以使用该动态库,需要将头文件 libsthc.h 拷贝到 /usr/include 目录下 ( 由于权限的问题 , 一般要以 root 的身分进行拷贝 ) 。

1.1 用 c 语言静态方式调用动态库 libsthc.so :

/*

* ctest.c

* Testing program for libsthc.so library

* in c languange

* by 玄机逸士

*/

#include "libsthc.h"

int main(void)

{

printf("%d\n", add(1, 2));

return 0;

}

#makefile:

ctest:ctest.o

gcc ctest.o -lsthc -o ctest

ctest.o:ctest.c

gcc -c ctest.c -o ctest.o

all:ctest

clean:

rm -f *.o ctest

1.2 用 c 语言动态方式调用动态库 libsthc.so :

/*cdltest.c*/

#include "stdio.h"

#include "stdlib.h"

#include "dlfcn.h"

int main(void)

{

void *handle;

int (*fcn)(int x, int y);

const char *errmsg;

/* open the library */

handle = dlopen("libsthc.so", RTLD_NOW);

if(handle == NULL)

{

fprintf(stderr, "Failed to load libsthc.so: %s\n", dlerror());

return 1;

}

dlerror();

//*(void **)(&fcn) = dlsym(handle, "add");            //ok

fcn = dlsym(handle, "add");                                   //ok

if((errmsg = dlerror()) != NULL)

{

printf("%s\n", errmsg);

return 1;

}

printf("%d\n", fcn(1, 5));

dlclose(handle);

return 0;

}

#makefile :

cdltest:cdltest.o

gcc cdltest.o -ldl -lsthc -o cdltest

cdltest.o:cdltest.c

gcc -c cdltest.c -o cdltest.o

all:cdltest

clean:

rm -f *.o cdltest

1.3 用 c++ 静态方式调用动态库 libsthc.so :

/*cpptest.cc*/

#include "libsthc.h"

using namespace std;

int main(void)

{

printf("%d\n", add(1, 2));

return 0;

}

#makefile:

cpptest:cpptest.o

g++ cpptest.o –o cpptest -lsthc

cpptest.o:cpptest.cc

g++ -c cpptest.cc -Wno-deprecated -o cpptest.o

all:cpptest

clean:

rm -f *.o cpptest

1.4 用 c++ 动态方式调用动态库 libsthc.so :

/*cppdltest.cpp*/

#include "stdio.h"

#include "stdlib.h"

#include "dlfcn.h"

int main(void)

{

void *handle;

int (*fcn)(int x, int y);

const char *errmsg;

/* open the library */

handle = dlopen("libsthc.so", RTLD_NOW);

if(handle == NULL)

{

fprintf(stderr, "Failed to load libsthc.so: %s\n", dlerror());

return 1;

}

dlerror();

*(void **)(&fcn) = dlsym(handle, "add");     //ok

//fcn = dlsym(handle, "add");                        //not ok in c++

if((errmsg = dlerror()) != NULL)

{

printf("%s\n", errmsg);

return 1;

}

printf("%d\n", fcn(1, 5));

dlclose(handle);

return 0;

}

#makefile

cppdltest:cppdltest.o

g++ cppdltest.o -ldl -lsthc -o cppdltest

cppdltest.o:cppdltest.cpp

g++ -c cppdltest.cpp -o cppdltest.o

all:cppdltest

clean:

rm -f *.o cppdltest

2. 用 c++ 语言写动态库:

/*

* libsthcpp.h

* Declarations for function cppadd

*/

#include "stdio.h"

#include "stdlib.h"

#include "stdarg.h"

#ifdef __cplusplus

extern "C"

{

#endif

int cppadd(int x, int y);

#ifdef __cplusplus

}

#endif

/*

* libsthcpp.cpp

* Implementation of function cppadd declared in libsthcpp.h

* in c++ language

*/

#include "libsthcpp.h"

int cppadd(int x, int y)

{

return x + y;

}

#makefile

libsthcpp.so:libsthcpp.o

g++ -g -shared -Wl libsthcpp.o -lc -o libsthcpp.so

libsthcpp.o:libsthcpp.cc libsthcpp.h

g++ -g -fPIC -c libsthcpp.cc -o libsthcpp.o

all:libsthcpp.so

clean:

rm -f *.o *.so

make 完成后,会生成一个动态库,即 libsthcpp.so 。为了使其他程序也可以使用该动态库,需要将库文件 libsthcpp.so 拷贝到 /usr/lib 目录下 ( 由于权限的问题,一般要以 root 的身分进行拷贝 ) ,为了使其他程序也可以使用该动态库,需要将头文件 libsthcpp.h 拷贝到 /usr/include 目录下 ( 由于权限的问题 , 一般要以 root 的身分进行拷贝 ) 。

2.1 用 c 语言静态方式调用动态库 libsthcpp.so :

/*

* ctest.c

* Testing program for libsthcpp.so library

* in c languange

* by 玄机逸士

*/

#include "libsthcpp.h"

int main(void)

{

printf("%d\n", cppadd(1, 2));

return 0;

}

#makefile

ctest:ctest.o

gcc ctest.o -lsthcpp -o ctest

ctest.o:ctest.c

gcc -c ctest.c -o ctest.o

all:ctest

clean:

rm -f *.o ctest

2.2 用 c 语言动态方式调用动态库 libsthcpp.so :

/*cdltest.c*/

#include "stdio.h"

#include "stdlib.h"

#include "dlfcn.h"

int main(void)

{

void *handle;

int (*fcn)(int x, int y);

const char *errmsg;

/* open the library */

handle = dlopen("libsthcpp.so", RTLD_NOW);

if(handle == NULL)

{

fprintf(stderr, "Failed to load libsthc.so: %s\n", dlerror());

return 1;

}

dlerror();

//*(void **)(&fcn) = dlsym(handle, "cppadd");       //ok in c and c++

fcn = dlsym(handle, "cppadd");                               //ok in c, but not in c++

if((errmsg = dlerror()) != NULL)

{

printf("%s\n", errmsg);

return 1;

}

printf("%d\n", fcn(1, 5));

dlclose(handle);

return 0;

}

#makefile

cdltest:cdltest.o

gcc cdltest.o -ldl -lsthcpp -o cdltest

cdltest.o:cdltest.c

gcc -c cdltest.c -o cdltest.o

all:cdltest

clean:

rm -f *.o cdltest

2.3 用 c++ 语言静态方式调用动态库 libsthcpp.so :

/*

* cpptest.cpp

* Testing program for libsthc.so library written in c language

* in c++ languange

* by 玄机逸士

*/

#include "libsthcpp.h"

#include "iostream.h"

int main(void)

{

cout << cppadd(1, 2) << endl;

return 0;

}

#makefile

cpptest:cpptest.o

g++ cpptest.o -lsthcpp -o cpptest

cpptest.o:cpptest.cpp

g++ -c cpptest.cpp -Wno-deprecated -o cpptest.o

all:cpptest

clean:

rm -f *.o cpptest

2.4 用 c++ 语言动态方式调用动态库 libsthcpp.so :

/*cppdltest.cpp*/

#include "stdio.h"

#include "stdlib.h"

#include "dlfcn.h"

int main(void)

{

void *handle;

int (*fcn)(int x, int y);

const char *errmsg;

/* open the library */

handle = dlopen("libsthcpp.so", RTLD_NOW);

if(handle == NULL)

{

fprintf(stderr, "Failed to load libsthc.so: %s\n", dlerror());

return 1;

}

dlerror();

*(void **)(&fcn) = dlsym(handle, "cppadd");         //ok in c and c++

//fcn = dlsym(handle, "cppadd");                             //ok in c, but not in c++

if((errmsg = dlerror()) != NULL)

{

printf("%s\n", errmsg);

return 1;

}

printf("%d\n", fcn(1, 5));

dlclose(handle);

return 0;

}

#makefile

cppdltest:cppdltest.o

g++ cppdltest.o -ldl -lsthcpp -o cppdltest

cppdltest.o:cppdltest.cpp

g++ -c cppdltest.cpp -o cppdltest.o

all:cppdltest

clean:

rm -f *.o cppdltest

补充:

显式调用动态库的要点:

显式调用的含义是代码出现库文件名,用户需要自己去打开和管理库文件。其要点为:

⑴把dlfcn.h系统头文件包含进来

⑵用dlopen函数打开库文件,并指定打开方式

dllope的的第一个参数为共享库的名称,将会在下面位置查找指定的共享库。

①环境变量LD_LIBRARY_PATH列出的用分号间隔的所有目录。

②文件/etc/ld.so.cache中找到的库的列表,由ldconfig命令刷新。

③目录usr/lib。

④目录/lib。

⑤当前目录。

第二个参数为打开共享库的方式。有两个取值

①RTLD_NOW:将共享库中的所有函数加载到内存

②RTLD_LAZY:会推后共享库中的函数的加载操作,直到调用dlsym()时方加载某函数

⑶用dlerror()函数测试是否打开成功,并进行错误处理;

⑷用dlsym获得函数地址,存放在一个函数指针中

⑸用获得的函数指针进行函数调用。

⑹程序结束时用dlclose关闭打开的动态库,防止资源泄露。

⑺用ldconfig工具把动态库的路径加到系统库列表中

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值