全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2728
推到 Plurk!
推到 Facebook!

如何使用LoadLibrary()匯入DLL內的class呢?

尚未結案
ENIX007
高階會員


發表:28
回覆:274
積分:185
註冊:2003-11-27

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-03-11 18:52:12 IP:210.243.xxx.xxx 未訂閱
各位好: 使用過DLL的大大們都知道要使用DLL內部的函式時,必須宣告一個函式指標與 該DLL函式相同的型態,才能使用GetProcAddress()來取得DLL函式位址... 而若是DLL匯出的是class呢?例如 class __declspec(dllexport) __stdcall MyClass { ... } 能否使用GetProcAddress()來取得該類別< > 先謝謝各位看倌< > 程式迷人之處,在於邏輯思考,然而卻也是惱人之處~~
------
程式迷人之處,在於邏輯思考,然而卻也是惱人之處~~
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-03-11 19:03:08 IP:140.135.xxx.xxx 未訂閱
ENIX007您好: 不曉得下面連結是不是您要的 < href="http://delphi.ktop.com.tw/topic.php?TOPIC_ID=32223">http://delphi.ktop.com.tw/topic.php?TOPIC_ID=32223 【發表】示範 DLL 中 export 一個 Class By dllee版主 順心 <>~我也是在學習的階段,回答的不好請您多多見諒與指教~
ENIX007
高階會員


發表:28
回覆:274
積分:185
註冊:2003-11-27

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-03-12 08:52:32 IP:210.243.xxx.xxx 未訂閱
taishyang版主您好 先謝謝您的回應,只是dllee版主在呼叫DLL內部class是使用靜態的方式... 也就是將*.lib檔加進專案中,因此該Source檔中有USELIB(Project1.lib)... 小弟是想說能不能使用動態呼叫的方式,亦即使用 LoadLibrary() & GetProcAddress()這組API的方式來做... 問題點在於GetProcAddress()回傳的是函式指標型態,如果使用一個一個 接class的member function這種方式的話,那class的member又該如何得知呢 程式迷人之處,在於邏輯思考,然而卻也是惱人之處~~
------
程式迷人之處,在於邏輯思考,然而卻也是惱人之處~~
brant
一般會員


發表:1
回覆:64
積分:23
註冊:2003-04-07

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-03-12 09:11:51 IP:202.145.xxx.xxx 未訂閱
第一個想到的是要用COM 建議您往這方面試試 不然只用他的概念應該也行 有dll及class的.h檔 dll裡面有一個factory function產生class object instance 然後把class的指標傳出來 client端的程式因為有.h檔,知道class的型態 去承接這個指標出來用 發表人 - brant 於 2004/03/12 09:15:11
ENIX007
高階會員


發表:28
回覆:274
積分:185
註冊:2003-11-27

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-03-12 10:41:48 IP:210.243.xxx.xxx 未訂閱
brant您好 以dllee版主的範例來說:  
引言:
DLL .H檔
//---------------------------------------------------------------------------
// 示範 DLL 中 export 一個 Class
// 2003-06-12 dllee http://dllee.ktop.com.tw
//---------------------------------------------------------------------------
// 在 .h 或 .hpp 中宣告 class A
class A
{
private:
  int   FValue;    public:
  __fastcall A(int Value);
  int  __fastcall GetA(void);
  void __fastcall SetA(int Value);
  A* __fastcall Generate(int Value);  //我加了這行
}; 
.CPP檔
#include "Unit1.h"    #pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
  return 1;
}
//----------------------------------------------------------------------------//
// 在 .cpp 中撰寫 class A 內的 method 並 export 出去
__declspec(dllexport) __fastcall A::A(int Value)
{
  FValue=Value;
}
//----------------------------------------------------------------------------//
__declspec(dllexport) int __fastcall A::GetA(void)
{
  return FValue;
}
//----------------------------------------------------------------------------//
__declspec(dllexport) void __fastcall A::SetA(int Value)
{
  FValue=Value;
}
//----------------------------------------------------------------------------//
__declspec(dllexport) A* __fastcall A::Generate(int Value)
{//這是我加的
    A* InstanceA = new A(Value);
    return InstanceA;
}
//----------------------------------------------------------------------------//
呼叫的時候:
.H檔
#ifndef Unit2H
#define Unit2H
//----------------------------------------------------------------------------//
#include 
#include 
#include 
#include <Forms.hpp>
#include "Unit1.h"
//----------------------------------------------------------------------------//
typedef A*(__fastcall *ClassFunc)(int Value);  //這是我加的
class TForm2 : public TForm
{
__published:        // IDE-managed Components
  TButton *Button1;
  TEdit *Edit1;
  TButton *Button2;
  TLabel *Label1;
  void __fastcall FormCreate(TObject *Sender);
  void __fastcall FormDestroy(TObject *Sender);
  void __fastcall Button2Click(TObject *Sender);
  void __fastcall Button1Click(TObject *Sender);
private:        // User declarations
  A *a;
public:                // User declarations
  __fastcall TForm2(TComponent* Owner);
  ClassFunc Generate;    //這是我加的
};
//----------------------------------------------------------------------------//
extern PACKAGE TForm2 *Form2;
.CPP檔
void __fastcall TForm2::FormCreate(TObject *Sender)
{//修改了這段
    HINSTANCE hDLL;
    hDLL = LoadLibrary("Project1.dll");
    (FARPROC &)Generate = GetProcAddress(hDLL,"Generate");
    a = Generate(100);
//  a=new A(100);
  Label1->Caption=String(a->GetA());
}
出來的結果Generate仍然指向NULL...接不到DLL內部傳出來的指標... 請問小弟這樣做是否有任何觀念上的錯誤呢 > 程式迷人之處,在於邏輯思考,然而卻也是惱人之處~~
------
程式迷人之處,在於邏輯思考,然而卻也是惱人之處~~
ENIX007
高階會員


發表:28
回覆:274
積分:185
註冊:2003-11-27

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-03-12 13:38:13 IP:210.243.xxx.xxx 未訂閱
試出來囉,只要把Generate()寫成一個全域函式,就可以了 仍然算是匯出函式,只不過函式內容是傳回一個物件指標罷了... 感謝 > 預祝你破 > 程式迷人之處,在於邏輯思考,然而卻也是惱人之處~~
------
程式迷人之處,在於邏輯思考,然而卻也是惱人之處~~
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-03-12 13:42:52 IP:140.135.xxx.xxx 未訂閱
問題能得以解決最重要,也謝謝您的心得分享
ENIX007
高階會員


發表:28
回覆:274
積分:185
註冊:2003-11-27

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-04-21 19:14:58 IP:210.243.xxx.xxx 未訂閱
補上測試OK的程式碼 < class="code">DLL .H檔 //--------------------------------------------------------------------------- // 示範 DLL 中 export 一個 Class // 2003-06-12 dllee http://dllee.ktop.com.tw //--------------------------------------------------------------------------- // 在 .h 或 .hpp 中宣告 class A class A { private: int FValue; public: __fastcall A(int Value); int __fastcall GetA(void); void __fastcall SetA(int Value); //A* __fastcall Generate(int Value); 放class內取不到 }; .CPP檔 #include "Unit1.h" #pragma argsused int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { return 1; } //----------------------------------------------------------------------------// // 在 .cpp 中撰寫 class A 內的 method 並 export 出去 extern "C" A* __stdcall Generate(int Value); //改放到這裡 __declspec(dllexport) __fastcall A::A(int Value) { FValue=Value; } //----------------------------------------------------------------------------// __declspec(dllexport) int __fastcall A::GetA(void) { return FValue; } //----------------------------------------------------------------------------// __declspec(dllexport) void __fastcall A::SetA(int Value) { FValue=Value; } //----------------------------------------------------------------------------// __declspec(dllexport) A* __fastcall A::Generate(int Value) {//這是我加的 A* InstanceA = new A(Value); return InstanceA; } //----------------------------------------------------------------------------// 呼叫的時候: .H檔 #ifndef Unit2H #define Unit2H //----------------------------------------------------------------------------// #include #include #include #include <Forms.hpp> #include "Unit1.h" //----------------------------------------------------------------------------// typedef A*(__fastcall *ClassFunc)(int Value); //這是我加的 class TForm2 : public TForm { __published: // IDE-managed Components TButton *Button1; TEdit *Edit1; TButton *Button2; TLabel *Label1; void __fastcall FormCreate(TObject *Sender); void __fastcall FormDestroy(TObject *Sender); void __fastcall Button2Click(TObject *Sender); void __fastcall Button1Click(TObject *Sender); private: // User declarations A *a; public: // User declarations __fastcall TForm2(TComponent* Owner); ClassFunc Generate; //這是我加的 }; //----------------------------------------------------------------------------// extern PACKAGE TForm2 *Form2; .CPP檔 void __fastcall TForm2::FormCreate(TObject *Sender) {//修改了這段 HINSTANCE hDLL; hDLL = LoadLibrary("Project1.dll"); (FARPROC &)Generate = GetProcAddress(hDLL,"Generate"); a = Generate(100); // a=new A(100); Label1->Caption=String(a->GetA()); } 這是配合GetProcAddress()必須回傳函式指標的變通方式 程式迷人之處,在於邏輯思考,然而卻也是惱人之處~~
------
程式迷人之處,在於邏輯思考,然而卻也是惱人之處~~
系統時間:2024-05-17 17:04:25
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!