Recently, someone asked in the Group how to use C language to compile DLL files (dynamic link library ).
I didn't care too much about this problem or try any solution. After all, I used VB (now I use it.. Net). Creating a DLL is just a click to create an ActiveX dll project. Today, I chatted with my friends online and read several files that he showed me. I suddenly realized the example of using mingw to compile the C program into a DLL file, it turns out that C Programs compile to DLL files only by adding a few specific modifiers before the interface function declaration to be made public. Therefore, Dev-CPP is used to create a default DLL document. Everything is clear. (I paste the source code below)
/* DLL. h file */
# Ifndef _ dll_h _
# DEFINE _ dll_h _
# If building_dll
# Define dllimport _ declspec (dllexport)
# Else/* Not building_dll */
# Define dllimport _ declspec (dllimport)
# Endif/* Not building_dll */
Dllimport void helloworld (void );
# Endif/* _ dll_h _*/
/* Dllmain. c file */
/* Replace "DLL. H" with the name of your header */
# Include "DLL. H"
# Include <windows. h>
# Include <stdio. h>
# Include <stdlib. h>
Dllimport void helloworld ()
{
MessageBox (0, "Hello world from DLL! /N "," Hi ", mb_iconinformation );
}
Bool apientry dllmain (hinstance hinst/* library instance handle .*/,
DWORD reason/* reason this function is being called .*/,
Lpvoid Reserved/* not used .*/)
{
Switch (reason)
{
Case dll_process_attach:
Break;
Case dll_process_detach:
Break;
Case dll_thread_attach:
Break;
Case dll_thread_detach:
Break;
}
/* Returns true on success, false on failure */
Return true;
}
Several explanations of the above Code:
1. _ declspec (dllexport): This is the key. It indicates that this function will become an external interface. (The following are some descriptions of dllexport, dllimport, and _ declspec I downloaded online ):
To use a function included in a DLL, you must import it. Dllimport is used to complete the import. Both dllexport and dllimport are extensions supported by VC (Visual C ++) and BC (Borland C ++. However, the dllexport and dllimport keywords cannot be used by themselves. Therefore, it must have another extension keyword _ declspec. The common format is __declspec (specifier). specifier is the storage class identifier. For DLL, specifier will be dllexport and dllimport. To simplify the description of the statement for importing and exporting functions, replace _ declspec with a macro name. In this program, dllexport is used. If your DLL is compiled into a C ++ program and you want the C program to use it as well, add the "c" connection description. # Define dllexport extern "C" _ declspec (dllexport) to avoid corruption of the Standard C ++ name. (Of course, if the reader is compiling a C program, do not add extern "C" because it is not needed and the compiler does not accept it ).
Ii. bool apientry dllmain () Description: (The following information is collected online)
1. Each dll must have an entry point. dllmain is a default entry function. Dllmain is responsible for initialization and termination. Whenever a new process or a new thread of the Process accesses the DLL, or when every process or thread accessing the DLL no longer uses the DLL or ends, it will call dllmain. However, using terminateprocess or terminatethread to end a process or thread does not call dllmain.
Dllmain function prototype:
Bool apientry dllmain (handle hmodule, DWORD ul_reason_for_call, lpvoid lpreserved)
{
Switch (ul_reason_for_call)
{
Case dll_process_attach:
.......
Case dll_thread_attach:
.......
Case dll_thread_detach:
.......
Case dll_process_detach:
.......
Return true;
}
}
Parameters:
Hmoudle: A handle that points to itself when the dynamic library is called (in fact, it is an selector pointing to the _ dgroup segment );
Ul_reason_for_call: indicates the reason why the dynamic library is called. When a process or thread loads or unmounts a dynamic Connection Library, the operating system calls the entry function and describes the reason why the dynamic Connection Library is called. All its possible values are:
Dll_process_attach: The process is called;
Dll_thread_attach: The thread is called;
Dll_process_detach: the process is stopped;
Dll_thread_detach: The thread is stopped;
Lpreserved: a parameter reserved by the system.
Here, I think you should have a general idea of compiling C programs into DLL files.
For the use of DLL files, I tested the following in VB.net:
Use vs.net 2003 to create a VB.net application.
Then reference the system. runtime. interopservices namespace in the project properties.
Add the following code to the default form file:
Public class form1
Inherits system. Windows. Forms. Form
# Region "code generated by Windows Form Designer"
Private sub form1_load (byval sender as system. Object, byval e as system. eventargs) handles mybase. Load
End sub
Private sub button#click (byval sender as system. Object, byval e as system. eventargs) handles button1.click
Hello ()
End sub
End Class
Module test
Sub main ()
Dim frm as new form1
Application. Run (FRM)
End sub
<Dllimport ("test. dll", entrypoint: = "helloworld", setlasterror: = true)> Public sub Hello ()
End sub
End Module
Then, put the test. dll generated with devcpp in the bin directory of the project, and the test is successful.
Some Ideas about DLL files:
For creating DLL files in multiple languages and dynamically using DLL files, I think plug-in technology is the most direct implementation method. In particular, the current. NET platform provides a simpler way to dynamically import functions in DLL files. The basic idea of implementing a plug-in can be to make a prescribed communication method in the main program and plug-in program. For example, to put an object that can represent the use of the plug-in function, the main program creates an object for the corresponding plug-in program, and is called by the plug-in program. The modified object contains the plug-in function information (such as the plug-in name and function pointer ), then, the main program will process it.
Here are some of the documents Excerpted from the Internet:
The dynamic link library defines two types of functions: the export function and the internal function ). Export functions can be called by other modules. Internal functions are used within the DLL program that defines them.
The following methods are used to output functions:
1. Traditional Methods
Specify the function or variable to be input in the export section of the module definition file. The syntax format is as follows:
Entryname [= internalname] [@ ordinal [noname] [data] [private]
Where:
Entryname is the name of the output function or data to be referenced;
Internalname is the same as entryname;
@ Ordinal indicates the sequence number (INDEX) in the output table );
Noname is used only when output by sequence number (entryname is not used );
Data indicates that a data item is output. The program that outputs data using DLL must declare this data item as _ declspec (dllimport ).
In the preceding items, only entryname is required, and other items can be omitted.
For a "C" function, entryname can be equivalent to the function name. For a "C ++" function (member function or non-member function), entryname is a modifier name. You can get the modified name of the function to be output from the. map image file, or use dumpbin/symbols to get the modified name, and then write them in the output module of the. Def file. Dumpbin is a tool provided by VC.
If you want to output a "C ++" class, write the data to be output and the modifier of the members to the. Def module definition file.
2. Output in the command line
Specify the/Export command line parameter for the link program Link and output the relevant functions.
3. Use the modifier _ declspec (dllexport) provided by MFC)
Add the _ declspec (dllexport) modifier before the declaration of the function, class, and data to indicate the output. _ Declspec (dllexport) removes the underline prefix of the output function name in the case of C call conventions and C compilation. Extern "C" makes it possible to use the C Compilation Method in C ++. To define the "c" function under "C ++", add the extern "C" keyword. Use extern "c" to indicate that the function uses the C compiling method. The output "C" function can be called from the "c" code.
For example, a C ++ file contains the following functions:
Extern "C" {void _ declspec (dllexport) _ cdecl test (INT var );}
The output function is named test.
MFC provides some macros for this purpose.
Afx_class_import :__ declspec (dllexport)
Afx_api_import :__ declspec (dllexport)
Afx_data_import :__ declspec (dllexport)
Afx_class_export :__ declspec (dllexport)
Afx_api_export :__ declspec (dllexport)
Afx_data_export :__ declspec (dllexport)
Afx_ext_class: # ifdef _ afxext
Afx_class_export
# Else
Afx_class_import
Afx_ext_api: # ifdef _ afxext
Afx_api_export
# Else
Afx_api_import
Afx_ext_data: # ifdef _ afxext
Afx_data_export
# Else
Afx_data_import
Macros such as afx_ext_class, if used in the implementation of DLL applications, it indicates the output (because _ afx_ext is defined, it is usually specified in the identifier parameter of the compiler/d_afx_ext ); if it is used in an application that uses DLL, it indicates the input (_ afx_ext is not defined ).
To output the entire class, use _ declspec (_ dllexpot) for the class. to output the member function of the class, use _ declspec (_ dllexport) for the function ). For example:
Class afx_ext_class ctextdoc: Public cdocument
{
...
}
Extern "C" afx_ext_api void winapi initmydll ();
Among these methods, the third method is recommended for ease of use. The second method is the first method. If output by sequence number, the call efficiency is higher. The second method is the second method.