動態連結程式庫中使用c++類的方法

來源:互聯網
上載者:User
以前的關於動態連結程式庫的寫法多是直接採用extern 'C'的方式來實現,但是如果採用類來編寫就會出現問題了,因為類在編譯時間是不能確定進入點位置的。這樣就產生了問題。怎麼來使用呢?前兩個方法是在linux下直接使用普通函數調用的方法來實現的。後邊的是在vc++中使用宏來對進入點動態調整輸入輸出__declspec(dllimport)和__declspec(dllexport)
  方法1:   把類作為參數傳入   介面函數中去:  
  //-----------------------   myclass.h   檔案-----------------    
  #ifndef   MYCLASS_H  
  #define   MYCLASS_H  
   
  class   myclass  
  {  
      public:  
          myclass(){}  
          ~myclass()   {}  
   
      public:  
          int   sum(int   a,int   b);  
       
      private:  
          int   _a;  
          int   _b;  
  };  
   
  #ifdef     SHARED  
  int           (*sum)(myclass   *my,int   a,int   b);  
  #else  
  int           sum(myclass   *my,int   a,int   b);  
  #endif  
   
  #endif   //   MYCLASS_H  
   
  //-----------------------   myclass.cpp   檔案-----------------    
  #include   "myclass.h"    
   
  int   myclass::sum(int   a,int   b)  
  {  
      int   c   =   a   +   b;  
      return   c;  
  }  
   
  int     sum(myclass   *my,int   a,int   b)  
  {  
    int   c   =   my->sum(a,b);  
    return   c;  
  }  
   
  //-----------------------   my.cpp   測試檔案   檔案-----------------    
  #include   <iostream>  
  #include <dlfcn.h>  
  #define   SOFILE "./my.so"  
   
  #define SHARED  
  #include "myclass.h"  
   
  using   namespace   std;  
   
  int   main(int   argc,   char   *argv[])  
  {  
      myclass   my;  
      void   *dp;  
      char   *error;  
       
    cout<<"動態連結程式庫應用示範"<<endl;  
     
    dp=dlopen(SOFILE,RTLD_LAZY); /*   開啟動態連結程式庫   */  
   
    if   (dp==0) /*   若開啟失敗則退出   */  
    {  
      cout<<"若開啟失敗則退出     dlopen"<<endl;    
      return(1);  
    }  
     
    sum=(int(*)(myclass   *my,int   a,int   b))dlsym(dp,"sum"); /*   定位求和函數   */  

   
    error=dlerror(); /*   檢測錯誤   */  
    if   (error) /*   若出錯則退出   */  
    {  
      cout<<"若出錯則退出   :定位求和函數   sum"<<endl;  
      return(1);  
    }  
   
      int   a   =   10;  
      int   b   =   100;  
      int   c   =   sum(&my,a,b); /*   調用此共用函數   */  
      cout<<"c   =   "<<endl;  
      system("PAUSE");  
      return   0;  
  }  
   
  編譯:  
  g++   myclass.h   myclass.cpp   -shared   -o   my.so        
  g++   my.cpp   -rdynamic   -lds   -o   my.exe               

    
  **********************************************************************  
   
  方法2:   聲名一個類的全域變數   然後在介面中使用這個全域變數:  
   
  //-----------------------   myclass.h   檔案-----------------    
  #ifndef   MYCLASS_H  
  #define   MYCLASS_H  
   
  /*  
    *   No   description  
    */  
  class   myclass  
  {  
      public:  
          myclass(){}  
          ~myclass()   {}  
   
      public:  
          int   sum(int   a,int   b);  
       
      private:  
          int   _a;  
          int   _b;  
  };  
   
  //聲名一個類的全域變數   然後在介面中使用這個全域變數:  
  extern     myclass   my;  
   
  #ifdef     SHARED  
  int           (*sum)(int   a,int   b);  
  #else  
  int           sum(int   a,int   b);  
  #endif  
   
  #endif   //   MYCLASS_H  
   
  //-----------------------   myclass.cpp   檔案-----------------    
  #include   "myclass.h"    
   
  int   myclass::sum(int   a,int   b)  
  {  
      int   c   =   a   +   b;  
      return   c;  
  }  
   
  int     sum(int   a,int   b)  
  {  
    int   c   =   my.sum(a,b);  
    return   c;  
  }  
   
  //-----------------------   my.cpp   測試檔案   檔案-----------------    
  #include   <iostream>  
  #include <dlfcn.h>  
  #define   SOFILE "./my.so"  
  #define SHARED  
  #include "myclass.h"  
   
  using   namespace   std;  
   
  int   main(int   argc,   char   *argv[])  
  {  
      //myclass   my;  
      void   *dp;  
      char   *error;  
       
    cout<<"動態連結程式庫應用示範"<<endl;  
     
    dp=dlopen(SOFILE,RTLD_LAZY); /*   開啟動態連結程式庫   */  
   
    if   (dp==0) /*   若開啟失敗則退出   */  
    {  
      cout<<"若開啟失敗則退出     dlopen"<<endl;    
      return(1);  
    }  
     
    sum=(int(*)(int   a,int   b))dlsym(dp,"sum"); /*   定位求和函數   */  
   
    error=dlerror(); /*   檢測錯誤   */  
    if   (error) /*   若出錯則退出   */  
    {  
      cout<<"若出錯則退出   :定位求和函數   sum"<<endl;  
      return(1);  
    }  
   
      int   a   =   10;  
      int   b   =   100;  
      int   c   =   sum(a,b); /*   調用此共用函數   */  
      cout<<"c   =   "<<endl;  
      system("PAUSE");  
      return   0;  
  }   
    
  編譯:  
  g++   myclass.h   myclass.cpp   -shared   -o   my.so   g++   my.cpp   -rdynamic   -lds   -o   my.exe  ************************************************************* 方法三:   在 DLL 的輸出標頭檔中用上: #ifdef MYLIBAPI #else   #define MYLIBAPI __declspec(dllimport) #endif 在 DLL 的 cpp 檔案中,引用標頭檔的前面加上: #define MYLIBAPI __declspec(dllexport)   注意,這時候 extern “C” 已經沒有了。因為我們要輸出的就是 C++ 類。 同時,在類的標頭檔中,類的定於前面寫上: class MYLIBAPI classname { } 這就 OK 啦。  *************************************************        #include <iostream>

using namespace std;

class DLLClass{
        public:
                // exported member function
                __declspec(dllexport) void functionA(void)
                {
                        cout << "In Function A of the exported function" << endl;
                        return;
                }
};

// exported class
class __declspec(dllexport) ExportDLLClass{
        public:
                void functionB(void)
                {
                        cout << "In Function B of the exported class" << endl;
                        return;
                }
};

// exported instance of the DLLClass
__declspec(dllexport) DLLClass test;
儲存成TestDLL.cpp然後進行編譯。呵呵,因為是用Editplus寫的代碼,所以要手動編譯哦^^
我用的是VS 2005的CL編譯介面CL.exe。在Cmd下:CL/c TestDLL.cpp
此時就產生了TestDLL.obj,然後進行連結:link TestDLL.obj /DLL
此時將產生TestDLL.dll,TestDll.exp,TestDll.lib三個檔案
工作暫告一個段落。。。。

然後開始寫調用TestDLL.dll的CallDLL.exe檔案:
 class DLLClass{
        public:
                // imported member function
        __declspec(dllimport) void functionA(void);
};

// imported class
class __declspec(dllimport) ExportDLLClass{
        public:
                void functionB(void);
};

// imported instance of the DLLClass
__declspec(dllimport) DLLClass test;

int main(void)
{
        ExportDLLClass TestClass;
                     test.functionA();
                     TestClass.functionB();
        return 0;
}

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.