免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 3502 | 回复: 22
打印 上一主题 下一主题

帮帮我!好心人! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-02-25 17:42 |只看该作者 |倒序浏览
主函数main
#include <stdio.h>;
#include <errno.h>;
#include <dlfcn.h>;
main () {
     char    (* myFun)();
     char    * handle;

     (void *)handle = dlopen("./libfuncso.so", RTLD_LAZY);
     printf("error == [%d]\n",errno);
     if(handle == NULL)
     {
         printf("dlopen = [%d] [%s]\n",errno,dlerror());
         return ;
     }

     (void *)myFun = (void(*)(int))dlsym(handle,"funcso";
     if (myFun == NULL)
     {
         printf("dlsym = [%d] [%s]\n",errno,dlerror());
         dlerror();
         return ;
     }
     if(dlclose(handle))
     {
         printf("dlclose = [%d] [%s]\n",errno,dlerror());
         return ;
     }
     return 0;
}

辅助函数:funcso.c
#include <stdio.h>;
#include <string.h>;
#include <stdlib.h>;
int funcso(){
    fprintf(stdout,"Where is funcso?!\n";
    return 0;
}
将funcso.c编译生成libfuncso.so
然后编译main生成main。运行后,显示:
¥ error == [109]

为什麽是这种结果,请大侠给予解答! 运行环境AIX4,3

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2003-02-25 17:50 |只看该作者

帮帮我!好心人!

为什么不把你帖子中的 “¥” 改成 "$" 呢?
如果你作为一个问问题的人,都对自己的帖子如此不重视,那么还会有谁重视呢?


根据你的意思,是打开动态链接库时失败,请把 dlerror() 的内容输出来让大家看一下。
  1. (void *)handle = dlopen("./libfuncso.so", RTLD_LAZY);
  2. printf("error == [%d]\n",errno);
  3. if(handle == NULL)
复制代码

改成
  1. (void *)handle = dlopen("./libfuncso.so", RTLD_LAZY);
  2. printf("error == [%d]\n",errno);
  3. fprintf( stderr, "errmsg: [%s]\n", dlerror() );
  4. if(handle == NULL)
复制代码

然后再运行一下。

论坛徽章:
0
3 [报告]
发表于 2003-02-25 17:55 |只看该作者

帮帮我!好心人!

可以使用perror得到errorno对应的提示信息

论坛徽章:
0
4 [报告]
发表于 2003-02-25 18:25 |只看该作者

帮帮我!好心人!

程序只输出了error == [109]
就结束了!

论坛徽章:
0
5 [报告]
发表于 2003-02-25 19:13 |只看该作者

帮帮我!好心人!

dlerror()的输出是空

论坛徽章:
0
6 [报告]
发表于 2003-02-25 19:18 |只看该作者

帮帮我!好心人!

if(handle == NULL)
{
printf("dlopen = [%d] [%s]\n",errno,dlerror());
return ;
}


if(handle == NULL)
{
perror("dlopen fail";
return ;
}

论坛徽章:
0
7 [报告]
发表于 2003-02-25 19:45 |只看该作者

帮帮我!好心人!

dlerror 输出是空的
但是handle却 is not null

论坛徽章:
0
8 [报告]
发表于 2003-02-25 19:45 |只看该作者

帮帮我!好心人!

使用perror看错误提示是什么

errorno没有什么用
因为你不知道这个errno对应的错误类型是什么(没有看头文件的话)

看了错误提示后对照man 页面看看是什么时候出现这个问题

论坛徽章:
0
9 [报告]
发表于 2003-02-25 19:52 |只看该作者

帮帮我!好心人!

perror 输出 Function not implemented

errno是于perror相对应的。

论坛徽章:
0
10 [报告]
发表于 2003-02-25 20:04 |只看该作者

帮帮我!好心人!

发信人: cpu (奔腾的心), 信区: Solaris  
标 题: Re: solaris中有类似windows的DLL有关的函数
发信站: 华南网木棉站 (Fri Aug 7 19:36:46 199, 转信  

【 在 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即可。  
(http://www.fanqiang.com)     进入【UNIX论坛】
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP