BCB writing DLL ultimate manual

zhaozj2021-02-11  218

Since the netizens are now in 9CBS, I will ask questions about BCB writing DLL, I wrote this article to throw brick

1. Write a DLL File / New / DLL to generate a DLL guide, then add export functions and export class export functions: ExportType FunctionName (DLLEXPORT) exporttype classname {. ..} example: (Description: Just generate a DLL.dll)

#include "dllform.h" // TDLLFRM definition

Useres ("DLL.RES"); UseForm ("DLLFORM.CPP", DLLFRM);

Class __declspec (dllexport) __stdcall mydllclass {// Export class public: mydllclass (); void createaform (); TDLLFRM * DLLMYFORM;};

TDLLFRM * DLLMYFORM2; Extern "C" __declspec (dllexport) __stdcall void createFromFunt (); // Export function

/ / -------------------------------------------------------------------------------------------- --------------------------- Int WinApi DLLENTRYPOINT (Hinstance Hinst, Unsigned Long REason, Void *) {Return 1;} // -------------------------------------------------- -----------------------

MYDLCLASS :: mydllclass () {}

Void mydllclass :: createaform () {dllmyform = new tdllfrm (application); dllmyform-> show ();} // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------- -void __stdcall createfromFunct () {dllmyform2 = new TdllFRM (Application); dllmyform2-> show ();

II. Static call DLL Generate lib files using $ bcb path / bin / implib.exe, add this file to the current directory in the project file, generate // unit1.h // TFORM1 definition #include "dllform.h" // TDLLFRM definition // ------------------------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

__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 Implement Void __fastcall tform1 :: button1click (TOBJECT * Sender) {// Export class implementation, export classes can only be used to call DLLClass = new mydllclass (); dllclass-> createaform ();} / / -------------------------------------------------------------------------------------------- --------------------------- void __fastcall tform1 :: button2click (TOBJECT * Sender) {// Export function implementation creteFromFunct ();} / / --------------------------------------------------- -------------------------- void __fastcall tform1 :: formclose (TCLOSEACTION & ACTION) {Delete Dllclass;

3. Dynamic call DLL // unit1.h class tform1: public tform {... private: // user declarations void (__stdcall * createfromfunct) (); ...}

// Unit1.cpp // TFORM1HINSTANCE DLLINST = NULL; VOID __FASTCALL TFORM1 :: Button2Click (TOBJECT * Sender) {if (null == dllinst) Dllinst = loadingLibrary ("dll.dll"); // DLL IF above (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 (TcloseAction & Action) {if (dllinst) freelibrary (dllinst);} 4. DLL as a MDICHILD (Sub-form) [Examples of Dynamic Call only] In fact, call the child form When the DLL is only checked whether the application's mainform is FSMDIFORM form, this is only

To pass the APPLICE of the calling program to the application; if you want to recover when you exit the DLL

Application

// MDIChildPro.cpp // Dll achieve CPP # include "unit1.h" // TForm1 defined TApplication * SaveApp = NULL; int WINAPI DllEntryPoint (HINSTANCE hinst, unsigned long reason, void *) {if ((reason == DLL_PROCESS_DETACH) && SaveApp) Application = SaveApp; // restore Application return 1;} extern "C" __declspec (dllexport) __stdcall void TestMDIChild (// 1024X768 TApplication * mainApp, LPSTR lpCaption) {if (NULL == SaveApp) // save Application, Pass Application {SaveApp;} // lpcaption to the Caption TFORM1 * FORM1 = New TFORM1 (); Form1-> show ();} Note: The above program is compiled using BCB 3.0 compilation success

Five BCB called VC prepared DLL 1. Name decomposition: No decomposition function TestFunction1 name of // __cdecl calling convention @ TestFunction2 // __fastcall calling convention TESTFUNCTION3 // __pascal calling convention TestFunction4 // __stdcall calling convention with the name of the decomposition function @ TestFunction1 $ QV // __cdecl calling convention @ TestFunction2 $ qv // __fastcall calling convention TESTFUNCTION3 $ qqrv // __apscal calling convention @ TestFunction4 $ qqrv // __stdcall calling convention to use extern "C" function name will not decompose

Generate a DEF file to see if the name decomposition is used using the ompdef mylib.def mylib.dll.

2. Call the agreement: __cdecl default is the default C format naming agreement of Borland C , which adds a scribe in front of the identifier to keep it the original identifier. The parameter passes the stack to the stack by the principle of the right one. Extaern "c" BOOL __CDECL TESTFUNCTION (); displayed as testfunction @ 1 in the DEF file: @ 1 indicates the number of functions, will be used when "use alias".

__pascal pascal format This time the function name is all turned to uppercase, the first parameter first stack, then clear the stack. TestFunction @ 1 // DEF file

__stdcall standard call the last parameter first stack, then clear the stack. TestFunction @ 1 // DEF file__fastcall passes the parameters to the first parameter of the register first stack, then clear the stack. @TestFunction @ 1 // DEF file

3. Resolve the call agreement: The difference between Microsoft and Borland's __stdcall is naming. Borland's way of __stdcall removed the next line before the name. Microsoft is before adding underline, add @, then follow the number of bytes reserved for the stack. The number of bytes depends on the space occupied by the argument. Each parameter is rounded up to 4 multiple times. This MiOCrosoft's DLL is different from the system's DLL.

4. Using an alias: Use the purpose of using the alias to make the call file .Obj matched with the DLL. DEF file. If there is no .def file, you should build one first. Then add the DEF file to Project. Use the alias should constantly modify external errors, if not, you also need to add the imports section to the DEF file. Imports testfunctiom4 = DLLPRJ.TESTFUNCTION4 TESTFUNCTIOM5 = DLLPRJ.WEP @ 500 TestFunctiom6 = DLLPRJ.GETHOSTBYADDR @ 51 Here you need to explain that calling applications. Obj name and DLL's .def file name is equivalent, and always. It doesn't even consider calling conventions, it will automatically match. In the previous example, the function is illustrated as __pascal, thus generating uppercase function names. This link will not be wrong.

5. Dynamic call example The code of the VC DLL is as follows: Extern "C" __DECLSPEC (DLLEXPORT) LPSTR __STDCALL BCBLOADVCWIN32STDCALL () {static char strretstdcall [256] = "bcb load vc_win32 dll by __stdcall mode is ok!";

Return Strretstdcall;}

Extern "c" __declspec (dllexport) LPSTR __CDECL BCBLOADVCWIN32CDECL () {static char strretcdecl [256] = "BCB LOAD VC_WIN32 DLL BY __CDECL MODE IS OK!";

Return strretcdecl;

Extern "C" __declspec (dllexport) LPSTR __FASTCALL BCBLOADVCWIN32FASTCALL () {static char strretfastcall [256] = "BCB LOAD VC_WIN32 DLL BY __FASTCALL MODE IS OK!";

Return strretfastcall;}

In fact, dynamic calls and DLLs written by calling BCB do not differ, the key is to view the DLL export function name to view TDUMP -EE MyDLL.DLL> 1.TXT (View "or DUMPBIN.EXE (VC tool) 1.TXT files can be) Since the VC6 does not support __pascall mode, the following three ways of example void __fastcall tform1 :: btnblvcwin32dynclick (Tobject * sender) {/ * cmd: tdbump vcwin32.dll> 1.txt Turbo Dump Version 5.0.16.4 Copyright (c) 1988, 1998 Borland International Display of File VCWIN32.DLLEXPORT ord: 0000 = 'BCBLoadVCWin32Fastcall ::' EXPORT ord: 0001 = 'BCBLoadVCWin32Cdecl' EXPORT ord: 0002 = '_ BCBLoadVCWin32Stdcall @ 0' * / if ( ! DllInst) DllInst = LoadLibrary ( "VCWin32.dll"); if (DllInst) {BCBLoadVCWin32Stdcall = (LPSTR (__stdcall *) ()) GetProcAddress (DllInst, "_BCBLoadVCWin32Stdcall @ 0"); // VC Dll // GetProcAddress (DllInst "BCBLOADVCWIN32STDCALL"); // BCB DLL if (bcbloadvcwin32stdcall) {ShowMessage (BCBLOADVCWIN32STDCALL ());} else showmessage ("can't find the __stdcall function! ");

BCBLoadVCWin32Cdecl = (LPSTR (__cdecl *) ()) GetProcAddress (DllInst, "BCBLoadVCWin32Cdecl"); if (BCBLoadVCWin32Cdecl) {ShowMessage (BCBLoadVCWin32Cdecl ());} else ShowMessage ( "Can not find the __cdecl Function!");

// Why? Is not 'bcbloadvcwin32fastcall ::', but '@ bcbloadvcwin32fastcall @ 0'? BCBLoadVCWin32Fastcall = (LPSTR (__fastcall *) ()) // GetProcAddress (DllInst, "BCBLoadVCWin32Fastcall ::"); GetProcAddress (DllInst, "@ BCBLoadVCWin32Fastcall @ 0"); if (BCBLoadVCWin32Fastcall) {ShowMessage (BCBLoadVCWin32Fastcall ());} else ShowMessage ("Can't Find The __fastcall function!" Else ShowMessage ("Can't Find The DLL!");} 6. Static call example static call is a bit trouble, from dynamic calls you can know the name of the export function , But directly (join the lib file to the project file)

The Linker prompt cannot find the implementation of the function from 4, you can join the DEF file connection (you can get the export table via the impdef mydll.def mydll.dll) to establish the same DEF file with the DLL file name to join the lib file to the project file. DEF files of DLL (Vcwin32.dll) are (vcwin32.def): library vcwin32.dll

IMPORTS @ BCBLoadVCWin32Fastcall = VCWIN32. @ BCBLoadVCWin32Fastcall @ 0 _BCBLoadVCWin32Cdecl = VCWIN32.BCBLoadVCWin32Cdecl BCBLoadVCWin32Stdcall = VCWIN32._BCBLoadVCWin32Stdcall@0

Corresponding to the function declaration and to achieve the following: extern "C" __declspec (dllimport) LPSTR __fastcall BCBLoadVCWin32Fastcall (); extern "C" __declspec (dllimport) LPSTR __cdecl BCBLoadVCWin32Cdecl (); extern "C" __declspec (dllimport) LPSTR __stdcall BCBLoadVCWin32Stdcall ();

void __fastcall TfrmStatic :: btnLoadDllClick (TObject * Sender) {ShowMessage (BCBLoadVCWin32Fastcall ()); ShowMessage (BCBLoadVCWin32Cdecl ()); ShowMessage (BCBLoadVCWin32Stdcall ());} Note: in BCB 5.0, it may not directly press F9 by Linker , Please first, BUILD, check: The above program uses BCB 5.0 and VC6.0 compiles successful

转载请注明原文地址:https://www.9cbs.com/read-4330.html

New Post(0)