我用BCB生成了一个dll,在dll当中定义了两个类(没有声明导出)和一个导出函数,实际是封装了一些XML操作。为简单起见,简化说明如下:这两个类是继承关系,一个名为Base,基类,只有虚的公有函数,无成员变量。另一个继承自Base,为其派生类,名为Creature,重载了那些虚函数,并且增加了自己的成员变量。导出函数Base  *  InitializeFile()的作用是new出一个Creature的对象,初始化成员变量,并返回该对象指针,但作为基类的指针返回。  
 
调用该DLL的程序头文件中,仅有Base类的声明,通过调用唯一的导出函数,得到一个Base类指针,当用这个指针调用相应函数时,实际使用的是Creature类中重载过的函数。  
 
使用BCB生成的应用程序调用该DLL(静态调用),一切正常。  
 
使用VC生成的应用程序调用该DLL(静态调用,有正确的lib文件),InitializeFile()函数返回的Base类实例指针正常,但使用它的成员函数时出错,跟踪进去看,发现能进入对应的Creature类实例重载后的函数,但是Creature的成员变量变成没有初始化过的了!于是出错。  
 
不明白原因,希望各位大虾帮帮我,感谢先,任务急啊!

解决方案 »

  1.   

    先动态调用以解决燃眉之急,bcb的lib和vc下的lib有点出入。但动态调用不会有问题。try it.
      

  2.   

    或可用vc自带的lib.exe生成vc下的lib
      

  3.   

    VC下的lib生成是正确的,是从DEF文件转的,应该没什么问题。
    现在经过调试,发现问题在于:返回的Base类实例指针的值,和进到成员函数中看到this的值不一样,变成一个毫无关系的内存地址。正确的情况应该是一样的,怎么会是啊?而使用BCB生成的应用程序调用该DLL(静态调用),一切正常。
      

  4.   

    BCB生成的DLL可以给VC调用,LIB 不可以给VC用。
    所以,或者动态调用(使用LoadLibraray和GetProcAddress);
    或者使用Lib.exe重新生成VC的LIB文件。
      

  5.   

    现在问题不是lib,已经生成了VC的,能用,而且动态调用也试过了。问题是调用起来后,通过类实例指针进到类成员函数后,看到this的值不是刚才指针的了,于是造成类成员变量无法使用而出错,怎么回事?而用BCB编写的主程序调用该DLL,则没有问题。所以很怀疑VC在对dll中的派生类使用是不是有些讲究,或者编译器有些选项没注意。不过我倒是把“结构成员对齐”参数在两种编译器上都设成1字节了,还是不行。
      

  6.   

    应该是编译器对类处理的不同造成的,VC需要对头文件里的Base类进行编译,头文件里的Base类的成员函数应该有空的函数体的吧?否则VC会报联接错误的。但是这个Base类的成员函数地址经过VC编译与BCB编译的DLL里的指针是不一致的,因为this指针就不符,所以无法调用。解决方法:导出所有Base类的成员函数,参数加一个Base类的指针。例:
    class Base
    {
    public:
       virtual void Func1(){}
       ...
    }
    导出函数Func1:
    extern void WINAPI Func1(Base* ptr);
    函数体:{ptr->Func1;}
    这样就把Base类的成员函数调用交还给了BCB,就没问题了。
      

  7.   

    上面的函数体少打了个括号,应该是:{ptr->Func1();}
      

  8.   

    还有导出函数的函数体不能放在头文件,即必须由BCB编译,不能让VC编译。
      

  9.   

    对,也可以用这个函数:
    extern void WINAPI Func1(Base* &ptr);
    或者 这个函数:
    extern Base*  WINAPI Func1();
      

  10.   

    还有:
    class Base
    {
    public:
       static void Func1(Base* &ptr);
       ...
    }
    你都试一下很好玩的。
      

  11.   

    谢谢ringphone(临风),按照你的方法解决了,也谢谢其它各位。给分!