vc调用dev动态链接库的方法

由于不同的编译器对函数的命名方法不同,使跨编译器进行动态库调用变得困难。对于调用g++的一般函数,在dev编写库文件时,在头文件中函数前声明extern "C",然后可以直接在vc中调用,但这种方法对于类是不行的。
下面介绍两种调用导出类的方法。
1.我们利用vc可以调用普通函数库的能力,将类成员函数全部转化为普通函数进行调用,这种方法的缺点是调用麻烦,封装性不好。
2.类似COM原理,我们用dev建立一个中间dll库,然后让vc调用这个中间库。在该库中,在头文件中建立一个抽象类,抽象类中的成员函数为要调用的链接库中的类的成员函数,并声明为虚函数,另外添加两个普通函数,作为与外界的接口,得到一个对象的指针和释放该指针,然后在源文件中建立它的派生类,添加一个成员变量为要导入类的对象,重写基类的成员函数,实现时利用成员变量调用导入类的函数。
例如,我们有一个只有声明的类,和其实现的dll和动态导入库.a文件。
class DLLIMPORT Column
{
  public:
    Column(double r,double h);
    virtual ~Column(void);
    double GetArea();
    double GetVolume();
    void SetRadical(double r);
    void SetHeight(double h);
  private:
  double radical;
  double height;
};
然后建立一个中间库,调用原始库,头文件声明为
class baseColumn
{
  public:
     virtual double _stdcall GetArea()=0;
     virtual double _stdcall GetVolume()=0;
     virtual void _stdcall SetRadical(double r)=0;
     virtual void _stdcall SetHeight(double h)=0;
  private:
};
extern "C"{
       DLLIMPORT baseColumn* _stdcall new_Column(double r,double h);
       DLLIMPORT void _stdcall delete_Column(baseColumn* bc);
}
实现中,定义一个派生类
class ColumnImp1:public baseColumn
{
      private:
             Column m_Column;
       public:
              _stdcall ColumnImp1(double r,double h);
              virtual double _stdcall GetArea();
              virtual double _stdcall GetVolume();
              virtual void _stdcall SetRadical(double r);
              virtual void _stdcall SetHeight(double h);
 };
每个实现调用Column类的成员函数,
 _stdcall ColumnImp1::ColumnImp1(double r,double h):m_Column(r,h){}

 double _stdcall ColumnImp1::GetArea()
 {
     return m_Column.GetArea();
  }
  double _stdcall ColumnImp1::GetVolume()
 {
        return m_Column.GetVolume();
  }
  void _stdcall ColumnImp1::SetRadical(double r)
 {
        m_Column.SetRadical(r);
  }
  void _stdcall ColumnImp1::SetHeight(double h)
 {
       m_Column.SetHeight(h);
  }
实现普通接口函数,
  baseColumn* _stdcall new_Column(double r,double h)
  {
      return new ColumnImp1(r,h);       
   }
  void _stdcall delete_Column(baseColumn* bc)
  {
      delete bc;  
  }
在vc源程序中调用中间库,采用显式链接如下,
 typedef baseColumn* (*pc1)(double,double);
 typedef void (*pc2)(baseColumn*);
 HINSTANCE Hind=LoadLibrary("libvirclass.dll");
 pc1 f1=(pc1)GetProcAddress(Hind,"new_Column");
 pc2 f2=(pc2)GetProcAddress(Hind,"delete_Column");

 baseColumn* bc=f1(1,1);
 cout<<bc->GetVolume()<<endl;
 cout<<bc->GetArea()<<endl;
 bc->SetRadical(2);
 bc->SetHeight(2);
 cout<<bc->GetVolume()<<endl;
 cout<<bc->GetArea()<<endl;
 f2(bc);
需要注意的地方是在声明普通函数时前面添加 extern "C",指定采用c编译方式,在中间库中类的所有函数都指定为_stdcall函数调用约定,同样vc中默认调用约定为_cdecl,更改为_stdcall,使保持一致。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值