_ Declspec (dllexport), extern "c" and. Def files

Source: Internet
Author: User

 _ Declspec (dllexport) and. Def files

In VC ++, if a DLL is generated, the. Def file is not used. You only need to add _ declspec (dllexport) before the Function Definition of VC ++. However, using _ declspec (dllexport) is different from using a. Def file. If the DLL is provided to VC ++ users, you only need to provide the. Lib generated during DLL compilation to users. It can easily call your DLL. However, if the DLL is used by VB, Pb, and Delphi users, it may cause a small problem. Because VC ++ converts the name of a function declared by _ declspec (dllexport), the following functions are provided:
_ Declspec (dllexport) int _ stdcall iswinnt ()
It will be converted to iswinnt @ 0, so that you must declare in VB as follows:
Declare function iswinnt lib "My. dll" alias "iswinnt @ 0" () as long
The number following @ may vary depending on the parameter type. This is obviously inconvenient. If you want to avoid this conversion, you must use the. Def file method.
The number after exports can be left blank, and the system will automatically allocate a number. For VB, Pb, and Delphi users, the method of calling by name is usually used. This number does not matter, but is used. for the VC program linked to Lib, it is not called by name, but by this number, so it is best to give. For example:
Exports
Test @ 1

Vc dll, the method called by Delphi:

/// K9rtexpr. h
Extern "C" _ decdll
Unsigned int _ stdcall k9rtsysinterrupt (INT ninterrupttag );

Extern "C" _ decdll
Unsigned int _ stdcall k9rtsysexprm (unsigned int nmoduletag,
Float ftimeout,
Void * ptestpar,
Void * presultpar
);

// K9rtexpr. cpp
# Include "k9rtexpr. H"
# Include "rtctrl. H"
Extern "C" _ decdll
Unsigned int _ stdcall k9rtsysinterrupt (INT ninterrupttag)
{
Return crelaytestcontrol: instance ()-> interrupttest (ninterrupttag );
}
Extern "C" _ decdll
Unsigned int _ stdcall k9rtsysexprm (unsigned int nmoduletag,
Float ftimeout,
Void * ptestpar,
Void * presultpar
)
{
Return crelaytestcontrol: instance ()-> relaytest (
Nmoduletag, ftimeout, ptestpar, presultpar );
}

/// K9rtexpr. Def
Library "k9rtexpr"
Description k9rtexpr Windows dynamic link library'

Exports
K9rtsysinterrupt
K9rtsysexprm
; Explicit exports can go here

// Delphi call File
Unit interfacefunc;

Interface

Uses
Unitdata, types;

Function k9rtsysexprm (nmoduletag: integer;
Utimeout: integer;
Ptestpar: pointer;
Presultpar: pointer): integer; stdcall;

Function k9rtsysinterrupt (ninterrupttype: integer): integer; stdcall;

Implementation
Const dllpath = 'rtbsexpr. dll ';
Function k9rtsysexprm; External dllpath name 'experimentrelaytest ';
Function k9rtsysinterrupt; External dllpath name 'interruptrelaytest ';

End.

 

Functions of extern "c" and. Def files

First, we need to know that C and C ++ compilers process function names differently. Second, they are two different products that are the same as C compilers, there are also differences in the way function names are processed during compilation, such as Microsoft Vc ++ and Dev C ++. Therefore, the extern "c" and. Def files are the processing methods introduced to solve these two situations.

1. Functions of extern "C"
For example, a C source program. c uses the library functions written in C ++. C # include "B. H ", where B. h contains the original declaration func of the function to be used. When the source program is compiled, the error "Link error, unresolved external symbols..." is found. Why?
The reason is that the C compiler compiles. c, compile func into func. When the link is connected, the linker searches for func in the C ++ library, however, when compiling the library, the C ++ compiler compiles func into _ FUNC @ YYY @ RRR. The natural linker cannot find the information of the corresponding function, so an error is reported! Is there any way to deal with this situation? -- When writing a C ++ library, you can add extern "c" to each function (or export function ", it indicates that the C ++ compiler processes the function name as a C compiler when compiling these functions. The function name in the generated library is func. When the C program calls the library function and compiles the link, the linker can find the desired information and the link is successful.

Second, the role of the. Def file (only related to VC ++ programming)
As mentioned above, there are some differences between the two C compilers developed by different vendors. The most prominent one is Microsoft's C compiler, which processes function names very specially (what is it like, you can use the dumpbin tool to view the DLL export function). Therefore, when you use a library written by another party, the program can be linked successfully. There are two methods: 1. The C compiler used by the database writer (VC ++ here) is obviously unreasonable. 2. The database writer uses the C compiler when using VC ++ to compile the database. def file.
. The function of the def file is to inform the compiler not to process the function name in Microsoft compiler mode, but to compile and export the function in a specified method (for example, there is a function func, let the compiler process the function name after it is still func ). In this way, you can avoid Link errors caused by the unique processing method of Microsoft Vc ++ compiler.

Use the. Def file to describe DLL output functions, such
Exports
Dllfun1 @ 1 noname
Dllfun2 @ 2 noname
Dllfun3 @ 3 noname
Dllfun4 @ 4 noname
...
@ Followed by the sequence number of the DLL output function, which must be between 1 and max (number of functions.
Use. after def declares the output function, do not declare the afx_ext_api or dllexport statement in the header file. After declaring the output function with extern "C", reference the header file of the original output function. If it is not declared with extern "C" (including with. Def), the header file does not need to be declared with afx_ext_api or dllexport.

 

_ Declspec (dllexport) and Def files and extern "C"
The scenario is as follows:
Use _ declspec (dllexport) to export functions in DLL, for example, to export int fun (void); display and call through loadlibrary () in exe program, and use getprocaddress () function to get the function address. failed to get the address. Check that the function name in the DLL has been compiled? Fun @ yahxz, pass the test, use? Fun @ yahxz to call getprocaddress () to obtain the fun address.
Later, the query details should use extern "c" to specify the C link. After the extern "C" is added, the verification is passed.

Then, I used the def file to export the function directly using exports fun, and did not add extern "c" to find that the function can also be used when displaying the call.

However, there is one sentence on msdn: Use. def file has the following Disadvantages: when exporting a function in a C ++ file, you must put the modifier name in. def file, or use the external "C" to define the export function with the standard C link to avoid name modification by the compiler.

However, I did not use the modifier name when using the. Def file. Instead, I directly used fun and didn't specify the C link, but it was successfully executed.

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.