討論區快速選單
知識庫快速選單
傑米的攝影旅遊筆記 網路投保旅行平安險
[ 回上頁 ] [ 討論區發言規則 ]
DLL export class的問題
更改我的閱讀文章字型大小
作者 : yohji(阿泰) C++ Builder卓越專家貼文超過500則
[ 貼文 566 | 人氣 3153 | 評價 3150 | 評價/貼文 5.57 | 送出評價 10 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/3/14 下午 12:53:17
請教大家:
我的環境是BCB
假設我有一個類別如下(利用GetA, SetA去存取m_nA), 我要怎麼做成dll 給VC or BCB使用這類別呢?

class TestClass
{
private:
    int m_nA;

public:

    int __stdcall GetA();
    void __stdcall SetA(int nValue);

};
作者 : windblown(windblown) VC++優秀好手C++ Builder曠世奇才C++卓越專家貼文超過1000則
[ 貼文 1105 | 人氣 890 | 評價 9400 | 評價/貼文 8.51 | 送出評價 200 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人yohji註記此篇回應為最佳解答 2007/3/15 上午 11:02:48
dll 無法使用 class, 所以使用 dll 的方法是不可能了
vc 與 bcb 的溝通只能用 dll, COM
結論1: 你可以想辦法把 class 改成 COM 來處理 --> 很大的工程, 我想你應該不會花這個時間
結論2: vc 與 bcb 無法溝通

bcb vs bcb 使用 class, 可以使用 borland 的 dll --> bpl
像我們使用 bcb 的 vclXX.bpl 就是你要的答案

相關資料,請參考 package 的撰寫。想要動態連結,請參考 LoadPackage()

因為我也不會寫,所以只能提供這一些資訊而已 ^_^
如果你有更好的資訊,也請提供,謝謝
作者 : yohji(阿泰) C++ Builder卓越專家貼文超過500則
[ 貼文 566 | 人氣 3153 | 評價 3150 | 評價/貼文 5.57 | 送出評價 10 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/3/15 下午 12:11:03
謝謝前輩的回應:
   ============================
   dll 無法使用 class, 所以使用 dll 的方法是不可能
   ============================
    我測試是可以(加入LIB靜態連結的方式),
   只是BCB產生的dll只能給BCB用...
    不能給VC用(LIB檔VC不接受,或許可以但我找不到可行的資料)
   時間緊迫,所以目前小弟只好先乖乖轉到VC上export dll了 > <
作者 : windblown(windblown) VC++優秀好手C++ Builder曠世奇才C++卓越專家貼文超過1000則
[ 貼文 1105 | 人氣 890 | 評價 9400 | 評價/貼文 8.51 | 送出評價 200 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/3/15 下午 02:43:02
我才應該謝謝你 ^^
我一直認為 class 無法在 dll 上使用, 原來是我誤解了

vc 無法使用 bcb 的 dll 應該有三個原因
1 lib 格式不一樣
2 cpp 轉換成底層的命名方式不同(c++ 標準沒有對此統一)
3 class 實作不同(c++ 標準沒有對此統一)

很謝謝你,修改了我的觀念
作者 : yohji(阿泰) C++ Builder卓越專家貼文超過500則
[ 貼文 566 | 人氣 3153 | 評價 3150 | 評價/貼文 5.57 | 送出評價 10 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/3/15 下午 05:00:45
前輩您客氣了 ^_^

我最後是參考下面連結的範例,把class export出來
http://www.codeproject.com/dll/RegDLL.asp

作者 : licheer(fon)
[ 貼文 19 | 人氣 1112 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2009/6/10 下午 03:28:55
請問可以說明, 怎麼把 vc 的類別,
做成 dll 給 VC or BCB 使用嗎?
謝謝
作者 : ice_emissary(燃燒的大地) 貼文超過200則
[ 貼文 408 | 人氣 0 | 評價 1890 | 評價/貼文 4.63 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/3/12 下午 06:39:44
我有看過人家用虛擬函式(virtual function)的方法做這件事,DLL 雖然不能匯出通用的 Class,但是虛擬函式還是能夠呼叫的到,我有用 BCB 和 VC 測試過。
用虛擬函式宣告所有成員函式,然後再用一般的 DLL 匯出方式匯出一個用來建立該 class 的函式。
作者 : ice_emissary(燃燒的大地) 貼文超過200則
[ 貼文 408 | 人氣 0 | 評價 1890 | 評價/貼文 4.63 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/3/18 下午 06:02:03
最近因為工作的需要而研究了這個東西,下面把簡化後的範例程式碼貼上。

註:對於 Lib 的部分不想在這裡詳述,那個只要用 BCB 的 implib 程式就行了。

==== 檔案一:TestDll.h ====
#ifndef TestDllH
#define TestDllH

#include <iostream>

// 定義 DLL 導出相關巨集
#ifdef __cplusplus
  #define DLL_EXTC extern "C"
#else
#define DLL_EXTC
#endif
#ifdef EXPORT_DLL_FUNCTION
  #define DLL_DECL __declspec(dllexport)
#else
#define DLL_DECL __declspec(dllimport)
#endif
#define DLL_EXPORT DLL_EXTC DLL_DECL

// DLL 類別公用介面
class TestBase
{
public:
  virtual __stdcall ~TestBase(){}
  virtual void __stdcall TestFunc(int x)=0;
};
// 用來建立 DLL 物件的公開函式
DLL_EXPORT TestBase* __stdcall CreateTestClass();

#endif

==== 檔案二:TestDll.cpp ====
// 這個放在建立 DLL 的 VC 專案,並在專案定義 EXPORT_DLL_FUNCTION。
// DLL 實做類別
#include <iostream>
#include "TestDll.h"
class Testclass : public TestBase
{
public:
  virtual __stdcall ~TestClass(){ std::cout << "Testclass destruction" << std::endl; }
  virtual void __stdcall TestFunc(int x){ std::cout << "Calling TestClass::TestFunc(" << x << ")" << std::endl; }
};

TestBase* __stdcall CreateTestClass()
{
  std::cout << "Testclass construction" << std::endl;
  return (TestBase*)(new TestClass);
}

==== 檔案三:main.cpp ====
// 使用範例,放在 BCB 專案。
#include "TestDll.h"
int main()
{
  // 建立 DLL 物件
  TestBase *Obj = CreateTestClass();
  // 使用物件
  Obj->TestFunc(10);
  // 銷毀物件
  delete Obj;

  return 0;
}
作者 : ice_emissary(燃燒的大地) 貼文超過200則
[ 貼文 408 | 人氣 0 | 評價 1890 | 評價/貼文 4.63 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/3/18 下午 06:02:13
最近因為工作的需要而研究了這個東西,下面把簡化後的範例程式碼貼上。

註:對於 Lib 的部分不想在這裡詳述,那個只要用 BCB 的 implib 程式就行了。

==== 檔案一:TestDll.h ====
#ifndef TestDllH
#define TestDllH

#include <iostream>

// 定義 DLL 導出相關巨集
#ifdef __cplusplus
  #define DLL_EXTC extern "C"
#else
#define DLL_EXTC
#endif
#ifdef EXPORT_DLL_FUNCTION
  #define DLL_DECL __declspec(dllexport)
#else
#define DLL_DECL __declspec(dllimport)
#endif
#define DLL_EXPORT DLL_EXTC DLL_DECL

// DLL 類別公用介面
class TestBase
{
public:
  virtual __stdcall ~TestBase(){}
  virtual void __stdcall TestFunc(int x)=0;
};
// 用來建立 DLL 物件的公開函式
DLL_EXPORT TestBase* __stdcall CreateTestClass();

#endif

==== 檔案二:TestDll.cpp ====
// 這個放在建立 DLL 的 VC 專案,並在專案定義 EXPORT_DLL_FUNCTION。
// DLL 實做類別
#include <iostream>
#include "TestDll.h"
class Testclass : public TestBase
{
public:
  virtual __stdcall ~TestClass(){ std::cout << "Testclass destruction" << std::endl; }
  virtual void __stdcall TestFunc(int x){ std::cout << "Calling TestClass::TestFunc(" << x << ")" << std::endl; }
};

TestBase* __stdcall CreateTestClass()
{
  std::cout << "Testclass construction" << std::endl;
  return (TestBase*)(new TestClass);
}

==== 檔案三:main.cpp ====
// 使用範例,放在 BCB 專案。
#include "TestDll.h"
int main()
{
  // 建立 DLL 物件
  TestBase *Obj = CreateTestClass();
  // 使用物件
  Obj->TestFunc(10);
  // 銷毀物件
  delete Obj;

  return 0;
}
作者 : ice_emissary(燃燒的大地) 貼文超過200則
[ 貼文 408 | 人氣 0 | 評價 1890 | 評價/貼文 4.63 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/3/18 下午 06:10:57
最近因工作需要,幾乎是瘋狂的測試不同編譯器(雖然也只有 VC 和 BCB)相互使用 DLL 的方式,也查閱了許多網路上說的方式。
這幾個日子下來得到一些心得感想,主要的心得其實還是在編寫 DLL 的方面,亦即 DLL 程式碼掌握在自己手上的時候。

註:
1. 產生 DLL 的專案以下稱為 "製造端"
2. 使用 DLL 的專案以下稱為 "使用端"

* 一般函式
  1. 注意在製造端與使用端對於 DLL 函式應定義為 "導入" 或 "導出" 的不同。
    對於大部分的 DLL 頭文件,通常需要在製造端定義一個指定的巨集。

  2. 所有導出函式都要以指定以 "C" 函式命名方式,除非限定製造端與使用端編譯器必須相同。

  3. 所有導出函式必須明確指定 Calling Convention,另外不要使用 __fastcall,因其在不同編譯器下的函式參數傳遞實做不同。

  4. 使用端動態載入 DLL 函式時注意要使用完整的函式名稱(即製造端加上修飾字後的函式實際導出名稱)

* 類別
  1. 儘量避免導出類別,因其他語言不支援類別或類別實做方式不同,除非限定使用端須為 C++ 編譯器。

  2. 勿直接導出整個類別或其成員函式,除非限定製造端與使用端編譯器必須相同。

  3. 將公開的成員函式以 virtual function 定義,以虛擬函式表查找取代使用 DLL 導出成員函式的方式。

  4. 設法限制、避免使用端直接建立或銷毀該類別,所有的相關動作必須由 DLL 進行,
    因為只有 DLL 內部知道類別完整內容與建立及銷毀所需動作。
     比如使用抽象類別(Abstract Class)定義 DLL 使用介面(防止使用端直接建立物件,而不是透過 DLL 函式為之);
     及定義虛擬解構函式讓使用端以 delete 敘述銷毀物件時能夠轉呼叫到 DLL 內的解構機制。

  5. 不要定義同名(不同參數)的重載虛擬函式,因其在虛擬函式表的排列順序於不同編譯器上不見得相同。
作者 : ice_emissary(燃燒的大地) 貼文超過200則
[ 貼文 408 | 人氣 0 | 評價 1890 | 評價/貼文 4.63 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/3/18 下午 10:16:23
最近因為一直研究通用 DLL 的關係,自然而然的對 COM 產生濃厚的興趣,開始看一些 COM 的相關資料。
也許是剛開始入門而已,學識淺薄的關係,我忽然發現原來 COM 的概念就是這樣而已嗎(物件封裝、虛擬函式、介面類別、實做類別)?
我以前一直聽說 COM 很難,還是說這只是我的錯覺而已!
 板主 : 徵求中
 > C++ Builder - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - C++ Builder - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
C++ Builder
1 windblown 5420 
2 Raynor 3120 
3 阿泰 2980 
4 workman 1650 
5 Linkin 1360 
6 CrazyStar 1260 
7 青衫 1160 
8 jonay 1080 
9 charlie 900 
10 小呆 770 
C++ Builder
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
0.09375