科技时代新浪首页 > 科技时代 > 滚动新闻 > 正文

Solaris 中类似 Windows 的DLL有关的函数


http://www.sina.com.cn 2006年10月09日 20:33 ChinaByte

  呵呵当然有,window那套动东东很多机制都是抄unix的

  比如system(32)\*.dll是就是仿照unix的/usr/lib/*.so

  unix的/usr/lib/*.so就是unix的动态库(dynamic library)

  给程序动态链接用的,反之/usr/lib/*.a是静态库,程序编译

  链接时就将相关函数链入目标文件。

  实际上泥cc -o yyy yyy.o -lXXX那个XXX就是告诉cc找/usr/lib/libXXX.so..

  yyy.o声明调用了libXXX.so中的函数,链接成功的目标文件yyy在运行时将动态

  调用libXXX.so的函数,至于cc -o yyy yyy.o libxxx.a那就不同了呵呵

  cc对-l参数的缺省链接方式是动态链接,即只链接符号,不链入函数实体。

  对链接方式可man ld。

  言归正传,既然有动态库,就肯定有与之相关的函数,window有LoadLibrary,

  偶solaris有dlopen,就是dynamic library open,window能让泥做

  土版DLL,偶solaris早就能让泥自己生产.so了呵呵,下面具体说明怎样调用

  动态库libXXX里的函数而又不需要在cc中指定-lXXX。

  首先是dlopen,格式:

  #include

  void * dlopen(const char *pathname, int mode);

  返回一个void *类型的handle,否则返回NULL。

  pathname就是泥所要打开的动态库,如果这个库声明链接了其它库,即对其它

  库有依赖关系,那么所有相关有依赖关系的库都会被打开,这些打开的库称之

  为组(group)。

  mode是打开方式:

  RTLD_LAZY:打开动态库后只重定位库中数据地址引用而不重定位而函数引用,

  函数引用在该函数要被激活时才定位,的确LAZY呵呵,但省开销;)

  RTLD_NOW: 与上者相比,动态库一被打开就重定位所有函数的引用。

  RTLD_GLOBAL:打开动态库里的全局符号可以被其它所有库重定位。

  RTLD_LOCAL: 打开动态库里的全局符号只能被同组库重引用。

  RTLD_GROUP: 只有相关组的符号才允许重定位??

  RTLD_PARENT:发dlopen调用的对象中的符号对被dlopen对象可见。

  RTLD_WORLD: 。。。呵呵太晦涩了我翻译的我都看不明白;(

  总之,一个RTLD_LAZY已经够用了呵呵;)

  然后是得到重定位的数据或函数引用:

  #include

  void *dlsym(void *handle, const char *name)

  意义明显,handle即dlopen的返回值,name即泥要引用的在动态库变量或函

  数名称。成功返回重定位后的符号地址,失败返回NULL。

  最后是关闭动态库:int dlclose(void *handle),

  一看就明白,懒得解释了;)

  下面给一个例子增加感性认识,该例子调用动态库client.so中的函数

  int client_request(char *),该函数返回0或-1并根据不同错误设置

  字符串err_info(也定义在client.so中):

  # include

  # include

  # include

  # define TRUE 0

  # define FALSE -1

  main( )

  {

  char buf[64];

  void *handle; /* 动态库句柄 */

  char *err_info; /* 要引用的动态库中的一个变量 */

  int (*client_request)(char *); /* 要引用的一个函数 */

  /* 打开动态库client.so */

  if ((handle = dlopen("client

  /* 得到函数名client_request的引用 */

  if ((client_request =

  (int (*)(char *))dlsym(handle, "client_request")) == NULL) {

  perror("dlsym client_request");

  exit(-1);

  }

  /* 得到变量名err_info的引用 */

  if ((err_info =

  (char *)dlsym(handle, "err_info")) == NULL) {

  perror("dlsym err_info");

  exit(-1);

  }

  for(;;) {

  gets(buf); /* 从标准输入读入命令串 */

  if (strcmp(buf, "exit") == TRUE) {

  dlclose(handle); /* 关闭动态库 */

  return 0;

  }

  printf("request:%s\n", buf);

  client_request(buf); /* 调用动态库中的函数 */

  printf("ask: %s\n", err_info); /* 引用动态库中的变量 */

  }

  }

  最后是编译问题,怎样编译成.so文件呢?很简单用ld或者cc -G就可以了,比如:

  cc -G yyy.so yyy.o others.o -ldl

  如果这个yyy.o有引用了其它动态库的函数呢?那么用cc -G ... -l了

  比如yyy.o引用了socket函数,那么

  cc -G yyy.so yyy.o others.o -ldl -lsocket即可。

爱问(iAsk.com)



论坛】【收藏此页】【 】【多种方式看新闻】【下载点点通】【打印】【关闭




科技时代意见反馈留言板 电话:010-82628888-5595   欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

Copyright © 1996 - 2006 SINA Inc. All Rights Reserved

新浪公司 版权所有