一. 編寫 DLL
File/New/Dll 生成 Dll 的嚮導,然後可以添加導出函數和導出類
導出函數:extern "C" __declspec(dllexport) ExportType FunctionName(Parameter)
導出類:class __declspec(dllexport) ExportType ClassName{...}
例子:(說明:只是生成了一個 DLL.dll )
#include "DllForm.h" // TDllFrm 定義
USERES("Dll.res");
USEFORM("DllForm.cpp", DllFrm);
class __declspec(dllexport) __stdcall MyDllClass { //導出類
public:
MyDllClass();
void CreateAForm();
TDllFrm* DllMyForm;
};
TDllFrm* DllMyForm2;
extern "C" __declspec(dllexport) __stdcall void CreateFromFunct();//導出函數
//---------------------------------------------------------------------------
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
return 1;
}
//---------------------------------------------------------------------------
MyDllClass::MyDllClass()
{
}
void MyDllClass::CreateAForm()
{
DllMyForm = new TDllFrm(Application);
DllMyForm->Show();
}
//---------------------------------------------------------------------------
void __stdcall CreateFromFunct()
{
DllMyForm2 = new TDllFrm(Application);
DllMyForm2->Show();
}
二. 靜態調用 DLL
使用 $BCB path/Bin/implib.exe 生成 Lib 文件,加入到工程文件中
將該文件拷貝到當前目錄,使用 implib MyDll.lib MyDll.dll 生成
// Unit1.h // TForm1 定義
#include "DllForm.h" // TDllFrm 定義
//---------------------------------------------------------------------------
__declspec(dllimport) class __stdcall MyDllClass {
public:
MyDllClass();
void CreateAForm();
TDllFrm* DllMyForm;
};
extern "C" __declspec(dllimport) __stdcall void CreateFromFunct();
class TForm1 : public TForm{...}
// Unit1.cpp // TForm1 實現
void __fastcall TForm1::Button1Click(TObject *Sender)
{ // 導出類實現,導出類只能使用靜態方式調用
DllClass = new MyDllClass();
DllClass->CreateAForm();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{ // 導出函數實現
CreateFromFunct();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
delete DllClass;
}
三. 動態調用 DLL
// Unit1.h
class TForm1 : public TForm
{
...
private: // User declarations
void (__stdcall *CreateFromFunct)();
...
}
// Unit1.cpp // TForm1
HINSTANCE DLLInst = NULL;
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if( NULL == DLLInst ) DLLInst = LoadLibrary("DLL.dll"); //上面的 Dll
if (DLLInst) {
CreateFromFunct = (void (__stdcall*)()) GetProcAddress(DLLInst,
"CreateFromFunct");
if (CreateFromFunct) CreateFromFunct();
else ShowMessage("Could not obtain function pointer");
}
else ShowMessage("Could not load DLL.dll");
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
if ( DLLInst ) FreeLibrary (DLLInst);
}
四. DLL 作爲 MDIChild (子窗體) 【只編寫動態調用的例子】
實際上,調用子窗體的 DLL 時,系統只是檢查應用程序的 MainForm 是否爲 fsMDIForm 的窗體,這樣
只要把調用程序的 Application 的 Handle 傳遞給 DLL 的 Application 即可;同時退出 DLL 時也要恢
復
Application
// MDIChildPro.cpp // Dll 實現 CPP
#include "unit1.h" // TForm1 定義
TApplication *SaveApp = NULL;
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
if ( (reason==DLL_PROCESS_DETACH) && SaveApp )
Application = SaveApp ; // 恢復 Application
return 1;
}
extern "C" __declspec(dllexport) __stdcall void TestMDIChild( //1024X768
TApplication* mainApp,LPSTR lpCaption)
{
if ( NULL == SaveApp ) // 保存 Application,傳遞 Application
{
SaveApp = Application;
Application = mainApp;
}
// lpCaption 爲子窗體的 Caption
TForm1 *Form1 = new TForm1 ( Application, lpCaption );
Form1->Show();
}
注:上面的程序使用 BCB 3.0 編譯成功
五. BCB 調用 VC 編寫的 DLL
1. 名字分解:
沒有名字分解的函數
TestFunction1 // __cdecl calling convention
@TestFunction2 // __fastcall calling convention
TESTFUNCTION3 // __pascal calling convention
TestFunction4 // __stdcall calling convention
有名字分解的函數
@TestFunction1$QV // __cdecl calling convention
@TestFunction2$qv // __fastcall calling convention