庞大资源库的计算机教程网站!
设为首页
加入收藏
总编信箱
投稿或申请专栏请先 [登 陆]
首页 操作系统 程序设计 图形图像 媒体动画 机械电子 WEB开发 数 据 库 办公系列 路由技术 网络原理 网络应用
认证考试 安全技术
首页>操作系统>Solaris>开发技术与原理>正文
资料搜索
Google搜索
Google
返回上级列表

推荐文章

快速保存网页中所有图片的方法
Windows中让光驱巧妙“隐身”技
防范非法用户入侵Win 2000/XP系
两款比较典型的ASP木马防范方法
有关表格边框的css语法整理
Windows XP中可以被禁用的服务
SQL Server导出导入数据方法
Javascript所有对象的属性的获
网页(HTML)中的特殊字符
与篮球共舞,尽显模式本色
QQ病毒的手工清除方法
Photoshop为极品美女打造性感睫
天衣无缝:IIS与PHP水火也相容
SQL Server存储过程编写和优化

solaris中有类似windows的DLL有关的函数吗?

 作者:奔腾的心    日期:2005-4-19
字号选择〖 〗/ 双击滚屏 单击停止   
【 在 irene (yoyo) 的大作中提到: 】
: 如题
呵呵当然有,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.so", RTLD_LAZY)) == NULL) {
perror("dlopen");
exit(-1);
}

/* 得到函数名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即可。
上一篇:soalris文件系统logging详解    下一篇:Sun数据存储系统浅说  
[发送给好友]  [关闭窗口]  [返回顶部]   转载请注明来源:www.it00.com   
特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。
责任编辑: 原点 投稿作者: 奔腾的心
信息来源: 网络 录入时间: 2005-4-19
关于我们 - 广告服务 - 版权申明 - 网站地图 - 联系方式 - 总编信箱 - 会员投稿