中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > C/C++
如何把派生类都做成不同的动态联接库,在主程序里动态的选择?
作者:未知 时间:2005-09-13 19:26 出处:ChinaUnix.net 责编:chinaitpower
              摘要:如何把派生类都做成不同的动态联接库,在主程序里动态的选择?

如何把派生类都做成不同的动态联接库,在主程序里动态的选择?


有一组从一个基类继承来的派生类,我想把这些派生类都做成
不同的动态联接库,

在主程序里面根据需要来动态的选择这些动态联接库,调用它们的类的方法,不知道如何实现?

请各位帮忙

 libad 回复于:2003-11-06 12:48:57
?

 wabc 回复于:2003-11-06 14:57:56
动态库分为前期绑定和后期绑定。

按你的要求,如果使用前期绑定,则要把所有的库载入,然后根据需要使用。

如果使用后期绑定,应该无法简单实现。

 libad 回复于:2003-11-10 14:57:48
需要后期绑定,根据需要动态选取相应的动态连接库,调用库中的子类
的相关函数。

好象dlopen,dlsym有用,有谁熟吗?有例子吗?

 老K 回复于:2003-11-10 17:28:55
C++编译后函数名称改变,应该无法用 dlsym。

 libad 回复于:2003-11-11 08:45:09
有什么办法吗?

 libad 回复于:2003-11-13 14:14:45
?

 river_wave 回复于:2003-11-13 14:25:13
main.cpp
class A
{
public:
     virtual int f() = 0;
}

main()
{
     dlopen("AA.so");
     dlsym("make_AA");
     A *a=make_AA();
    a->f();
}

AA.cpp
class AA : public A
{
   virtual int  f();
}

A * make_AA()
{
     return new AA;
}
将AA.cpp编译到AA.so里即可了

 bingocn 回复于:2003-11-13 14:29:09
不理解。。。。

动态链接库本来就是干这个的啊,在运行时进入.so中,编译时只提供一个入口。
你说的问题是C++的多态吧?

 老K 回复于:2003-11-13 14:52:18
[quote:d599732fde="river_wave"]main.cpp
class A
{
public:
     virtual int f() = 0;
}

main()
{
     dlopen("AA.so");
     dlsym("make_AA");
     A *a=make_AA();
    a->f();
}

AA.cpp
class AA : public A
{
   v..........[/quote:d599732fde]

验证了吗?有用?什么环境?

 libad 回复于:2003-11-14 09:31:43
把AA.cpp编译为dll后,调用dlopen失败。

但如果把函数A* make_AA()从AA.cpp中去掉,dlopen就可以成功,
为什么?vpHandle=dlopen(“libaa.so",RTLD_LAZY);

我用的是solaris 2.6 C++4.2

 libad 回复于:2003-11-17 09:27:46
?

 libad 回复于:2003-11-17 09:51:24
刚才的问题解决了,dlopen可以打开成功了,但到dlsym中就出错了,

是否真是C++编译后函数名称改变,无法用 dlsym?        vpHandle=dlopen(argv[1],RTLD_LAZY);
        if(vpHandle==NULL) {
        printf("\nopen %s\n",argv[1]);
        perror("dlopen");
                return NULL;
        }

        printf("\nopen success...\n");


        A *myClass;

    A* (*function)();
    function=(A* (*)())dlsym(vpHandle,"make_AA");
    if(function==NULL) {
                perror("dlsym");
                dlclose(vpHandle);
                return NULL;
    }

。。。。。。。。。。。

 老K 回复于:2003-11-17 10:15:32
哎,说了,就是不信。

 river_wave 回复于:2003-11-17 10:46:48
你看看dlsym抱什么错?这种方法是完全可行的,因为我做的一个东西就是这么实现的(AIX、RedHat都在运行,很正常);如果有符号的转译,你可以用 "extern "C" "这个预编译标识符强行申明C的函数不做C++方式的名字转换!

 libad 回复于:2003-11-18 09:59:05
perror打出的错为:
dlsym: Error 0 ,没有详细的信息了。

我已经加上了
extern "C" {
    #include <dlfcn.h>
     void *dlsym(void *handle, const char *name);
}
还是不行呀。

 river_wave 回复于:2003-11-18 10:31:13
使用dlerror取错误描述(看看你的操作系统是否有);

看看这种呢
extern "C" { 
A *make_AA(); 
}

 libad 回复于:2003-11-19 18:10:11
加了,现报错:

ld.so.1: ./dll: 致命的: 重定位错误: 文件./libtest.so: 符号__0oCAActv: 参照的符号没有找到
被杀掉

libtest.so是编译为库的子类的AA.cpp

 libad 回复于:2003-11-24 16:40:46
?

 river_wave 回复于:2003-11-24 17:47:55
贴出你的例子来吧

 libad 回复于:2003-11-26 11:07:10
AA.cpp

class AA : public A
{
public:
 AA();
 ~AA();
 int f();
};

int AA::f() {
return 0;
}

extern "C" {
A * make_AA();
}
A * make_AA()
{
return new AA();
}

class A
{
public:
virtual int f() ;
};


main 程序:
main(int argc,char *argv[]) {

        char *cpClassName;
        int i;
        int j;
        int k;
        void *vpHandle;

        if(argc!=2) {
            printf("\nUsage:\n\t%s lib_name\n",argv[0]);
            return -1;
        }

        //open the specific dynamic library.
        vpHandle=dlopen(argv[1],RTLD_LAZY);
        if(vpHandle==NULL) {
        printf("\nopen %s\n",argv[1]);
        perror("dlopen");
                return NULL;
        }

        printf("\nopen success...\n");


        A *myClass;

    A* (*function)();
    function=(A* (*)())dlsym(vpHandle,"make_AA");
    if(function==NULL) {
                perror("dlsym");
                dlerror();
                dlclose(vpHandle);
                return NULL;
    }

    myClass=(*function)();
    myClass->f();


    dlclose(vpHandle);
    return 0;
}

 river_wave 回复于:2003-11-26 16:33:57
看__0oCAActv和你的程序,应该是你的AA的构造和析构没有实现,__0oCAActv好像是构造函数的转换后的名字;由于你没有实现,当然找不到了;这种方法肯定可以实现你的要求,而且例子基本上已经实现,只是有些细节问题你需要注意一下,好好看看,改改错,离成功不远矣

 libad 回复于:2003-11-28 14:54:49
谢谢!!!!!!!!!!

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有