VC調用BCB生成DLL中的類成員函數問題


想來是個老問題了:
定義一個接口類(基類),其聲明放在頭文件中,供VC程序包含,成員函數都是存虛的。
用BCB做了個DLL,中有導出的“類工場”函數,返回一個實現類(由接口類派生下來,成員函數實現具體功能)指針。
現在用VC調用這個DLL,可以成功得到“類工場”函數返回的指針,也能通過其調用進實現類的成員函數,但是,函數的參數值總是傳不對。第一個參數值是正確的,第二個參數(int型)值在調用時無論給成多少,傳過來的始終是this指針的值。
請問這是什么問題?該如何解決?以往總是通過在DLL中重新定義一些導出函數來執行調用類成員函數的操作,以此回避VC編譯的程序直接通過類指針調用BCB編譯的DLL中的類成員函數,現在想把這個問題搞清楚,徹底解決一下了。

13 个解决方案

#1


bcb那個函數的調用方式是什么。
bcb的函數一般情況下都會習慣寫__fastcall

#2


bcb和vc最好用com

#3


你將所有的類成員方法都聲明成__stdcall試試看,不過這是不推薦的這樣調用,還有不少未知的問題在里面

推薦 使用COM,或者寫成標准DLL

#4


用COM吧------導出類也只是調用類的public下的方法. 用接口不是更好嗎

#5


謝謝樓上諸位,寫DLL時我已經把全部函數的調用方式聲明成了__stdcall,在VC中也選了默認為__stdcall以避免問題。com不會用啊,不知道編寫、使用方便不。哪位能再幫我分析一下?

#6


關注

#7


你試試用BCB代碼調用你的DLL會不會有同樣的問題。
仔細檢查下代碼。如果用的是標准的DLL那么無論什么語言封裝的都是一樣,只是外部調用接口格式不同。

#8


樓上的,用BCB調用是沒有問題的,這個問題長期以來一直困擾我,有時候我做兩個版本DLL,給VC用的就在DLL內部用函數封裝一下,不把那個類指針傳出來。

#9


C++沒有二進制標准,所以出問題很正常。
COM和標准DLL都有二進制標准,所以不會有啥問題的。

#10


自己頂一下,看看還有啥辦法沒?

#11


以前的一個帖子,希望對樓主有所幫助,特別是最后一個例子。如果能調試通過,就ok了

1 樓greatefish(大魚)回復於 2002-03-12 12:06:24 得分 20
當然可以!   
  要注意的是:   
  1:在寫DLL的export部分時一定要用   __stdcall修飾符   
  2:因為在BCB中兼容很多PASCAL語法,如__fastcall等修飾符號,   
      在開發DLL   for   vc時一定要避免使用這些東西.   
  Top

2 樓ddeng(登登)回復於 2002-03-12 12:15:06 得分 30
字符串參數傳遞時得用char   *,不能用AnsiString,VC不認識!   
  另外DLL生成以后,在VC中若要靜態連接就得用VC的工具重新生成LIB文件,BCB生成的LIB文件VC中是不能使用的。   
  Top

3 樓kingcaiyao(aking)回復於 2002-03-12 12:59:45 得分 50
當然,可以,在寫函數時可以用__stdcall,也可以用__cdecl。不過接下來調用,就要注意,很多朋友出問題都在這里,動態調用就沒有什么,三個函數:LoadLibrary,GetProcAddress,FreeLibrary,靜態調用因為需要將.lib加入到項目中,因為VC生成的LIB格式與BCB的LIB格式不同,因此需要轉換,可以用implib來進行轉換,如果你在VC中寫輸出函數時,用__cdecl,那么就應該帶一個參數implib   -a   *.lib   *.dll,如果用__stdcall就不用帶-a參數,即:implib   *.lib   *.dll   
    
  要么你使用coff2omf   
  Top

4 樓wangxd(東東)回復於 2002-03-12 13:09:39 得分 0 
同意樓上的。不過用vc開發的dll在bcb中靜態連接時,用不用用bcb的implib重新生成lib文件?Top

5 樓ddeng(登登)回復於 2002-03-12 16:27:54 得分 0 
當然要,要用Borland的implib導出LIB。Top

6 樓fallegend(fall)回復於 2002-03-13 15:32:26 得分 0 
在BCB中新建DLL,加入一個Form   
  加入代碼:   
  #ifndef   _SHOWIMG_H_     
  #define   _SHOWIMG_H_     
  #ifndef   IMGDLL     
  #define   EXTERN   __declspec(dllimport)     
  #else     
  #define   EXTERN   __declspec(dllexport)     
  #endif     
  extern   "C"   EXTERN   void   __stdcall   ShowF(void);     
  #endif     
    
  void   _export   _stdcall   ShowF(void)   
    {   
  Form1   =   new   TForm1(NULL);   
  Form1->ShowModal();   
  delete   Form1;   
  }   
    
  在VC中加入調用代碼顯示FORM:   
  void   CVcdlltestDlg::OnButton1()     
  {   
  void   (*ShowF)(void);     
  HINSTANCE   hInst;     
  hInst   =   LoadLibrary("test.DLL");     
  (FARPROC   &)ShowF=GetProcAddress(hInst,"ShowF");     
  ShowF();     
  FreeLibrary(hInst);     
  //   TODO:   Add   your   control   notification   handler   code   here   
    
  }   

#12


謝謝樓上的,但是最后一個例子也沒解決問題,它通過在DLL內部用Form1->ShowModal(),避免了在VC中利用Form1指針調用ShowModal()的問題,這和我以前的解決方法是一樣的,現在想搞清楚為啥不能在DLL中生成Form1,傳遞給VC程序,在VC程序中,使用Form1->ShowModal()。

#13


這個問題其實很容易的,在VC 中打開匯編代碼,然后會看到,調用成員函數的時候,this 指針是用 ecx 寄存器來傳得,而在 BCB 中 this 指針不使用 ecx 具體使用什么忘記了,可以打開匯編看看。因為這個差別,所以使用導出純虛基類這種方式在BCB 和VC直接使用共享庫是不可以的,而只能使用導出函數的方式。

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: