Many netizens are asking questions about how to compile DLL in BCB.
1. Write DLL
File/New/DLL to generate the DLL wizard, and then you can add the export function and export class
Export function: extern "C" _ declspec (dllexport) exporttype functionname (parameter)
Export class: Class _ declspec (dllexport) exporttype classname {...}
Example: (Note: Only a DLL. dll is generated)
# 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 createfromfunct (); // export the Function
//---------------------------------------------------------------------------
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 ();
}
Ii. Static Call DLL
Use $ BCB path/bin/implib.exe to generate the Lib file and add it to the project file.
Copy the file to the current directory and use implib mydll. Lib mydll. DLL to 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 implementation
Void _ fastcall tform1: button1click (tobject * sender)
{// Export class implementation. The export class can only be called in static mode
Dllclass = new mydllclass ();
Dllclass-> createaform ();
}
//---------------------------------------------------------------------------
Void _ fastcall tform1: button2click (tobject * sender)
{// Export function implementation
Createfromfunct ();
}
//---------------------------------------------------------------------------
Void _ fastcall tform1: formclose (tobject * sender, tcloseaction & Action)
{
Delete dllclass;
}
Iii. Dynamic DLL call
// 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"); // The above DLL
If (dllinst ){
Createfromfunct = (void (_ stdcall *) () getprocaddress (dllinst,
"Createfromfunct ");
If (createfromfunct) createfromfunct ();
Else showmessage ("cocould not obtain function pointer ");
}
Else showmessage ("cocould not load DLL. dll ");
}
Void _ fastcall tform1: formclose (tobject * sender, tcloseaction & Action)
{
If (dllinst) freelibrary (dllinst );
}
Iv. dll as mdichild (sub-form) [write a dynamic call example only]
In fact, when calling the DLL of the sub-form, the system only checks whether the mainform of the application is fsmdiform.
You only need to pass the handle of the application that calls the program to the application of the DLL. At the same time, you need to restore the application that exits the DLL.
Application
// Mdichildpro. cpp // DLL to implement CPP
# Include "unit1.h" // tform1 Definition
Tapplication * saveapp = NULL;
Int winapi dllentrypoint (hinstance hinst, unsigned long reason, void *)
{
If (reason = dll_process_detach) & saveapp)
Application = saveapp; // restore the application
Return 1;
}
Extern "C" _ declspec (dllexport) _ stdcall void testmdichild (// 1024x768
Tapplication * mainapp,
Lpstr lpcaption)
{
If (null = saveapp) // Save the application and pass the application
{
Saveapp = application;
Application = mainapp;
}
// The lpcaption is the sub-Form Caption.
Tform1 * form1 = new tform1 (application, lpcaption );
Form1-> show ();
}
Note: The above program is successfully compiled using BCB 3.0.
V. BCB call the DLL compiled by VC
1. Name breakdown:
No name decomposition Function
Testfunction1 // _ cdecl calling convention
@ Testfunction2 // _ fastcall calling convention
Testfunction3 // _ Pascal calling convention
Testfunction4 // _ stdcall calling convention
Functions with name Decomposition
@ Testfunction1 $ QV // _ cdecl calling convention
@ Testfunction2 $ QV // _ fastcall calling convention
Testfunction3 $ qqrv // _ apscal calling convention
@ Testfunction4 $ qqrv // _ stdcall calling convention
Using extern "C" does not break down the function name
Use impdef mylib. Def mylib. DLL to generate the def file and check whether name decomposition is used.
2. Call conventions:
_ Cdecl default
It is the default C format naming convention of Borland C ++. It underlines before the identifier to retain
All the original full-process identifiers. The parameter is passed to the stack based on the rightmost parameter priority principle, and then the stack is cleared.
Extaern "C" bool _ cdecl testfunction ();
In the def file
Testfunction @ 1
Note: @ 1 indicates the number of sequential functions, which will be used when an alias is used.
_ Pascal format
In this case, all function names are written in uppercase. The first parameter first presses the stack and then clears the stack.
Testfunction @ 1 // def File
_ Stdcall standard call
The last parameter first presses the stack and then clears the stack.
Testfunction @ 1 // def File
_ Fastcall: Pass the parameter to the Register
The first parameter first presses the stack and then clears the stack.
@ Testfunction @ 1 // def File
3. Solution call conventions:
The difference between Microsoft and Borland's _ stdcall is the naming method. Borland
_ Stdcall removes the underline before the name. Microsoft is prefixed with an underscore
Add @, followed by the number of bytes reserved for the stack. The number of bytes depends on the space occupied by the parameter in the stack. Every
All parameters are rounded to a multiple of 4. The Miocrosoft DLL is different from the system DLL.
4. Alias:
The alias is used to match the call file. obj with the. Def file of the DLL. If no
Create a. Def file first. Add the def file to the project. Aliases should be used continuously
Modify an external error. If not, add the imports part to the def file.
Imports
Testfunctiom4 = dllprj. testfunction4
Testfunctiom5 = dllprj. WEP @ 500
Testfunctiom6 = dllprj. gethostbyaddr @ 51
It must be noted that the. OBJ name of the calling application is equivalent to the. Def File Name of the DLL,
And always. You don't even need to consider the call Convention. It will automatically match. In the previous example, the function is
The description is _ Pascal. Therefore, an upper-case function name is generated. In this way, the linked program will not go wrong.
5. Dynamic call example
The vc dll Code 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 calling is no different from calling the DLL compiled by BCB. The key is to view the DLL export function name.
You can use tdump.exe (BCB tool) or dumpbin.exe (VC tool) to view
Tdump-ee mydll. dll> 1.txt (view the 1.txt file)
Vc6 does not support the _ pascall method. The following is an example of three methods:
Void _ fastcall tform1: btnblvcwin32dynclick (tobject * sender)
{
/* Cmd: tdbump vcwin32.dll> 1.txt
Turbo dump version 5.0.16.4 copyright (c) 1988,199 8 Borland International
Display of file vcwin32.dll
Export 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't find the _ cdecl function! ");
// Why? 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 little troublesome. you can know the name of the exported function from the dynamic call, but directly (add the Lib file to the project file)
Linker prompts that the function implementation cannot be found
From 4 we can see that the def file connection can be added.
(You can use impdef mydll. Def mydll. DLL to obtain the export table)
Create a Def file with the same DLL file name and add it to the project file together with the Lib File
The def file of the above DLL (vcwin32.dll) is (vcwin32.def ):
Library vcwin32.dll
Imports
@ Bcbloadvcwin32fastcall = vcwin32. @ bcbloadvcwin32fastcall @ 0
_ Bcbloadvcwin32cdecl = vcwin32.bcbloadvcwin32cdecl
Bcbloadvcwin32stdcall = vcwin32. _ bcbloadvcwin32stdcall @ 0
The corresponding function description and implementation are as follows:
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, you may not be able to directly press F9 through linker. Please build it once first.
Note: The above program is successfully compiled using BCB 5.0 and vc6.0.