What you can learn from writing DLLs (1)--exporting functions

Source: Internet
Author: User
Tags export class

Candle Autumn Http://www.cnblogs.com/cswuyg/archive/2011/09/30/dll.html

There are two ways to use dynamic-link libraries, one for explicit invocation. One is an implicit invocation.

(1) Explicit invocation: Use LoadLibrary to load a dynamic-link library and use GetProcAddress to get a function address.

(2) Implicit invocation: You can use #pragma comment (lib, "XX.lib"), or you can directly add XX.lib to the project.

DLL authoring

When writing DLLs, there is an important problem to solve, that is, the function rename--name-mangling. There are two kinds of solutions, one is directly in the code to solve the use of extent "C", _declspec (dllexport), #pragma comment (linker, "/export:[exports name]=[mangling Name ], the other is a def file.

(1) When writing DLLs, why there is extern "C"

Cause: The renaming rules for C and C + + are not the same. This renaming is called "name-mangling" (name decoration or name adaptation, identifier renaming, some people translated as "name shredding", this translation seems a little confusing)

It is said that the C + + standard does not stipulate the name-mangling scheme, so different compilers use different, for example: Borland C + + Mircrosoft C + + is different, And maybe different versions of the compiler their name-mangling rules are also different. In this case, the target files are compiled by different compilers. obj is not universal, because the same function, using different name-mangling, will have different names in the obj file. If the function renaming rules in the DLL are inconsistent with the renaming rules used by the user of the DLL, then this function will not be found.

The C standard stipulates the specification of C language Name-mangling (Lin Rui's book has said so). This makes it possible for any compiler that supports the C language to compile the obj file to be shared and linked to an executable file. This is a standard, and if the DLL and its users adopt such a convention, then it is possible to resolve the error caused by inconsistent function renaming rules.

In addition to the differences between C + + and C, the difference between the compiler and the name of the symbol, consider the name mangling caused by the calling convention. such as the extern "C" __stdcall call method will be added to the original function name to write the symbol of the parameter, while the extern "C" __cdecl will not append additional symbols.

A function in a DLL is indexed as a function name or function number when it is invoked. This means that DLL files generated by the Name-mangling method of C + + with a compiler may not be generic. Because their function names are renamed differently. In order to make the DLL common, often use C's name-mangling way, that is, each export function is declared as extern "C", and the use of _stdcall calling convention, and then also need to rename the exported function, in order to export the non-decorated function name.

Note that the role of extern "C" is to solve the problem of function symbol name, which is required for both the producer of the dynamic link library and the user of the dynamic link library.

The explicit loading of a dynamic-link library is through the GetProcAddress function, which obtains the function address according to the dynamic link library handle and the function name. Because GetProcAddress is only operating system-related, may operate a variety of compiler-generated DLLs, its parameters in the function name is the full function name, without any modification, so it is generally necessary to ensure that the DLL ' function name is the original function name. In two steps: one, if the export function uses the extern "C" _cdecl, then there is no need to rename, this time the name of the DLL is the original name, if the use of extern "C" _stdcall, when the function name in the DLL is decorated, you need to rename. There are two ways to rename, either use the *.def file, modify it outside the file, or use #pragma to give the function alias in the code.

(2) The role of _declspec (dllexport) and _declspec (dllimport)

_declspec also has additional uses, which are discussed only with DLL-related uses. Just like the keywords in parentheses, export and import. _declspec (dllexport) is used on DLLs to illustrate that this is an exported function. _declspec (dllimport) is used in the program that invokes the DLL to illustrate that this is a function imported from a DLL.

_declspec (dllexport) is necessary because the DLL must state that the function is to be used for export. But in a different way, you can use DEF files to describe which functions are used for export, as well as the number of functions inside the def file.

The use of _declspec (dllimport) is not necessary, but it is advisable to do so. Because if you do not use _declspec (dllimport) to indicate that the function is imported from a DLL, then the compiler does not know where this function is, the generated EXE will have a call xx instruction, this xx is a constant address, XX address is a jmp DWORD PTR[XXXX], jumps to the function body, obviously so that there is no reason for an intermediate jump. If _declspec (dllimport) is used to illustrate, then the call DWORD Ptr[xxx] is generated directly, so there is no extra jump. (Refer to "Encryption and decryption" in the third edition of Page 279)

(3) Impact of __stdcall

This is how a function is called. By default, the VC uses __cdecl function call mode, if the resulting DLL will only be used for C + + programs, then there is no need to define the __stdcall call method, if you want to WIN32 assembly use (or other __stdcall call way of the program), Then you can use __stdcall. This may not be important because you can set the rules for a function call when you call a function. Like VC can be set to call the function, so it is convenient to use Win32 assembly generated DLL. But __stdcall this calling convention will be name-mangling, so I think VC default calling convention is simpler. However, if you have to __stdcall the calling convention, and the function name is not decorated, you can use the *.def file, or give the function an alias in #pragma way in the code (this way you need to know what the modified function name is).

Example:

extern "C" __declspec (dllexport) bool __stdcall Cswuyg ();

extern "C" __declspec (dllimport) bool __stdcall cswuyg ();

• #pragma comment (linker, "/export:[email protected]")

(4) Purpose of the *.def file

Specifies the export function and tells the compiler not to use the decorated function name as the exported function name, but to export the function with the specified function name (such as a function func, so that the function name is still func after the compiler is processed). This avoids link errors due to the unique handling of the Microsoft VC + + compiler.

That is, the use of DEF files, it does not require the extern "C", you can also do not need __declspec (dllexport) (However, DLL manufacturers in addition to provide a DLL, but also to provide a header file, need to add this extern "C" in the header file and calling conventions, because the user needs to follow the same rules as the manufacturer, unless the user and the manufacturer use the same compiler and have no special requirements for the calling convention.

Example def file format:

LIBRARY XX (DLL name this is not required, but must be guaranteed to be the same as the generated DLL name)

Exports

[function name] @ [function ordinal]

After writing, add to the VC project, it is OK.

Also, note that if you want to use __stdcall, you must use the __stdcall in your code, because the *.def file is only responsible for modifying the function name and is not responsible for calling the Convention.

That is, the Def file is just the function name, regardless of how the function balances the stack.

If the *.def file is added to the project, the link does not automatically add it in. Then you can do this:

Manually add in Link:

1) The project Propertiesàconfiguration Propertiesàlinkeràcommand Lineà in the "Additional options" add:/def:[full file name].def

2) The project propertiesàconfiguration propertiesàlinkeràinputàmodule Definition file plus [full file name].def

Note that even with the name decoration of C, the resulting function name may be decorated. For example, in the VC, _stdcall call method, the function name will be decorated, preceded by ' _ ', followed by parameters related to other things. Therefore, it is very important to use the *.def file to name the function.

(5), DllMain function

Each dynamic link library will have a DllMain function. If the DllMain function is not defined at the time of programming, then the compiler will add it to you.

DllMain function Format:

BOOL apientry DllMain (HANDLE hmodule,

DWORD Ul_reason_for_call,

LPVOID lpreserved

)

{

Switch (Ul_reason_for_call)

{

Case Dll_process_attach:

printf ("\nprocess Attach of DLL");

Break

Case Dll_thread_attach:

printf ("\nthread Attach of DLL");

Break

Case Dll_thread_detach:

printf ("\nthread Detach of DLL");

Break

Case Dll_process_detach:

printf ("\nprocess Detach of DLL");

Break

}

return TRUE;

}

(6), many have not learned, such as: Export class, export variables, DLLs more advanced applications. At present, we should understand the basic knowledge. Later on.

2011-8-14 Supplement

Writing a DLL you can use a. def file to name the exported function name.

1, the necessity of dynamically loading DLLs, renaming (*.DEF)?

Because the exported function uses the __stdcall call method whenever possible. In the case of __stdcall, the function name is decorated either by name mangling of C or by the name mangling of C + +. Therefore, after using the __stdcall invocation method, the function name must be renamed using the *.def file, or you cannot use GetProcAddress () to get the function pointer through the function name.

2, when the implicit call, the header file to pay attention to the place?

Because using static loading, a header file is required to declare the function in the DLL to be used, if __stdcall or extern "C" is specified in the declaration, then when the function is called, the compiler will go through the function name after name mangling. lib to find this function, *. def The content in *.lib does not work on the name of the function in the *.def file, and the function renaming in the files is only useful for DLLs . This has the Lib and DLL in the function name inconsistent problem, but does not have an impact, DLL manufacturers and users are using a consistent function declaration.

3, so in the end should not use __stdcall it?

I see some of the code is not using __stdcall. If you do not use __stdcall, use the default calling convention _cdecl and have extern "C". Then the VC will not be any modification. In this way, the function name in the generated DLL is the original function name. You can also not use the. def file.

There are also some requirements that must be used for __stdcall, such as COM-related things, system callback functions. Specifically see if there is any need.

4. How do I write the exported function aliases?

You can write an alias to the function name in the. def file.

For example:

Exports

Cswuygtest (alias) = [email protected] (function to export)

Or:

#pragma COMMENT (linker, "/export:[alias" =[namemangling name] ")

This makes it possible to modify the alias arbitrarily, without the error of not finding the symbol.

5. Do not use *.def files?

If you adopt the VC default calling convention, you can use the *.def file, if you want to adopt the __stdcall calling convention, and do not want the function name to be decorated, then use the *.def file bar, another way to write in the code is not easy to rename.

6, under what circumstances (not) need to consider the problem of function renaming?

1), implicit invocation (via Lib)

If the manufacturer of the DLL and the user of the DLL use the same language, the same programming environment, then you do not need to consider function renaming. When the user calls the function, the function name after the name mangling can be found in Lib.

If the manufacturer of the DLL is using a different language than the DLL, or a different compiler, then you need to consider renaming.

2), display call (via Getprocessaddress)

This is definitely a function that must be considered for renaming.

7. Summary

In general, when writing a DLL, write a header file that declares the function's namemingling, calling convention (mainly for implicit invocation). Write a *.def file to rename the function (mainly for explicit invocation). Provide *. Dll\*.lib\*.h to the user of the DLL, so whether the implicit invocation, or explicit invocation, can be done conveniently.

Report:

An example of a simple DLL export function: Http://files.cnblogs.com/cswuyg/%E7%BC%96%E5%86%99DLL%E6%89%80%E5%AD%A6%E6%89%80%E6%80%9D.rar

Learning materials:

Http://www.cnblogs.com/dongzhiquan/archive/2009/08/04/1994764.html

Http://topic.csdn.net/u/20081126/14/70ac75b3-6e79-4c48-b9fe-918dce147484.html

What you can learn from writing DLLs (1)--exporting functions

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.