Msdn DLL Synthesis

Source: Internet
Author: User
Tags export class xslt
Export from DLL using def File

The module definition (. Def) file is a text file that contains one or more module statements describing various DLL attributes. If you do not use_ Declspec (dllexport)If the keyword is used to export the DLL function, the DLL needs the. Def file.

The. Def file must contain at least the following module definition statements:

  • The first statement in the file must be a library statement. This statement identifies the. Def file as a DLL. The library statement is followed by the DLL name. The linker puts this name into the DLL Import and Export Database.

  • The exports statement lists the names and, if possible, the serial number values of the DLL export function. Assign the sequence number to the function by adding the @ sign and a number after the function name. When the sequence number value is specified, the sequence number range must be from 1 to n, where N is the number of DLL export functions. If you want to export functions by sequence number, see export functions from DLL by sequence number rather than by name and this topic.

For example, the DLL containing the Code that implements the binary search tree may look like the following:

LIBRARY   BTREE
EXPORTS
Insert @1
Delete @2
Member @3
Min @4

If you use the mfc dll Wizard to create an mfc dll, The Wizard will create the main. Def file for you and automatically add it to the project. Add the function name to export to this file. For non-mfc dll files, you must create a. Def file and add it to the project.

If you export a function in the C ++ file, you must put the modifier name in the. Def file, or use external "C" to define an export function with a standard C link. To put the modifier name in the. Def file, you can use the dumpbin tool or the/map linker option to obtain the modifier name. Note that the modifier generated by the compiler is specific to the compiler. If you place the modifier name generated by the visual C ++ compiler. def file, the application linked to the DLL must also be generated using the same version of Visual C ++, so that the modifier name in the application can be called with the DLL. the exported names in the def file match.

If the extension DLL is generated and exported using the. Def file, place the following code at the beginning and end of the header file containing the export class:

#undef AFX_DATA
#define AFX_DATA AFX_EXT_DATA
// <body of your header file>
#undef AFX_DATA
#define AFX_DATA

These lines of code ensure that the MFC variables used internally or the variables added to the class are exported (or imported) from the extension DLL. For exampleDeclare_dynamicThis macro extendsCruntimeclassAdd member variables to the class. Saving these four lines of code may result in incorrect compilation or link to the DLL, or errors when the client application is linked to the DLL.

When a DLL is generated, the linker uses the. Def file to create the exported (. exp) file and the imported (. Lib) file. Then, the linker uses the exported file to generate the DLL file. The executable file that is implicitly linked to the DLL is linked to the import/export warehouse during production.

Note that MFC uses the. Def file to export functions and classes from mfcx0.dll.

Export functions from DLL by serial number rather than by name

The simplest way to export functions from a DLL is to export them by name. For example_ Declspec (dllexport)This method is used. However, you can also export functions by serial number. When using this technology, you must use the. Def file instead_ Declspec (dllexport). To specify the sequence number of a function, append the sequence number to the function name in the. Def file. For information on the specified sequence number, see export from DLL using the. Def file.

Use _ declspec (dllexport) to export data from DLL

Microsoft introduced_ ExportTo enable the compiler to automatically generate export names and put them in a. Lib file. Then, the. Lib file can be used to link to the DLL like static. Lib.

In the updated compiler version, you can use_ Declspec (dllexport)Keyword: exports data, functions, classes, or class member functions from DLL._ Declspec (dllexport)The Export command is added to the object file, so you do not need to use the. Def file.

This convenience is the most obvious when you try to export a C ++ modifier. Because there is no standard specification for name modification, the name of the export function may change in different compiler versions. If you use_ Declspec (dllexport). The DLL and dependent. EXE files must be re-compiled only when any naming conventions are changed.

Many export commands (such as serial numbers, noname, and private) can only be created in the. Def file, and these attributes must be specified using the. Def file. However, we also use the. Def file._ Declspec (dllexport)Will not cause generation errors.

To export a function,_ Declspec (dllexport)The keyword must appear on the left side of the call Convention keyword (if a keyword is specified ). For example:

__declspec(dllexport) void __cdecl Function1(void);

To export all public data members and member functions in the class, the keywords must appear on the left of the class name, as shown below:

class __declspec(dllexport) CExampleExport : public CObject
{ ... class definition ... };

When a DLL is generated, a header file containing the exported function prototype and/or class is usually created, and_ Declspec (dllexport)Add it to the declaration in the header file. To improve code readability_ Declspec (dllexport)Define a macro and use the macro for each symbol being exported:

#define DllExport   __declspec( dllexport ) 

_ Declspec (dllexport)Store the function name in the DLL export table. To optimize the table size, see export functions from DLL by sequence number rather than by name.

Export C ++ functions for executable files in C Language

If a DLL written in C ++ has functions that you want to access from the C language module, use the C link instead of the C ++ link to declare these functions. Unless otherwise specified, the C ++ compiler uses the C ++ type security Naming Convention (also known as name modification) and C ++ call conventions (it is very difficult to use this call convention to call from C ).

To specify a C link, specify a C link for the function declaration.Extern"C". For example:

extern "C" __declspec( dllexport ) int MyFunc(long parm1);

Export C functions for executable files in C or C ++

Use_ CplusplusThe Preprocessor macro determines the language being compiled, and then, if used from the C ++ language module, declare these functions using the C link. If this technology is used and header files are provided for DLL, these functions can be used by C and C ++ users intact.

The following code demonstrates the header files that can be used by C and C ++ client applications:

// MyCFuncs.h
#ifdef __cplusplus
extern "C" { // only need to export C interface if
// used by C++ source code
#endif

__declspec( dllimport ) void MyCFunc();
__declspec( dllimport ) void AnotherCFunc();

#ifdef __cplusplus
}
#endif

If you need to link the C function to the C ++ executable file, and the function declaration header file does not use the above technology, add the following content to the C ++ source file to prevent the compiler from modifying the c Function Name:

extern "C" {
#include "MyCHeader.h"
}

Use afx_ext_class to export and import data

Extended DLL usageAfx_ext_classMacro export class; Use the macro import class to link to the executable file of the extended DLL. The same header file used to generate the extension DLL can beAfx_ext_classMacros are used together with executable files linked to DLL.

In the DLL header fileAfx_ext_classThe keyword is added to the class declaration as follows:


class AFX_EXT_CLASS CMyClass : public CDocument
{
// <body of class>
};

When the pre-processor symbol is defined_ AfxdllAnd_ AfxextThe macro is defined_ Declspec (dllexport). However, when_ AfxdllBut Not Defined_ AfxextThe macro is defined_ Declspec (dllimport). Pre-processor symbol after Definition_ AfxdllIndicates that the shared MFC version is being used by the target executable file (DLL or application. When_ AfxdllAnd_ AfxextThis indicates that the target executable file is an extension DLL.

When exporting from an extended DLL,Afx_ext_classIs defined_ Declspec (dllexport)Therefore, you can export the entire class without placing the modified names of all the symbols of the class in the. Def file. This method is used by the MFC example dllhusk.

Although this method can avoid creating all the modified names of the. Def file and class, it is more efficient to create a. Def file because the names can be exported by serial number. To use the. Def File Export method, place the following code at the beginning and end of the header file:


#undef AFX_DATA
#define AFX_DATA AFX_EXT_DATA
// <body of your header file>
#undef AFX_DATA
#define AFX_DATA
Warning

Be careful when exporting inline functions because they may cause version conflicts. Inline functions are extended to application code. Therefore, inline functions will not be updated unless the application itself is re-compiled if inline functions are rewritten later. Generally, you can update the DLL function without generating a new application that uses the DLL function.

Export individual members in the class

Sometimes, you may want to export individual members in the class. For example, if you exportCdialogDerived class, you may only need to export the constructor andDomodalCall. You can useAfx_ext_class.

For example:


class CExampleDialog : public CDialog
{
public:
AFX_EXT_CLASS CExampleDialog();
AFX_EXT_CLASS int DoModal();
...
// rest of class definition
...
};

You no longer export all the members of the class, but you may encounter other problems due to the way the MFC macro works. Several MFC helper macros actually declare or define data members. Therefore, you must export the data members from the DLL.

For example, when an extension DLL is generated,Declare_dynamicMacro is defined as follows:

#define DECLARE_DYNAMIC(class_name) \
protected: \
static CRuntimeClass* PASCAL _GetBaseClass(); \
public: \
static AFX_DATA CRuntimeClass class##class_name; \
virtual CRuntimeClass* GetRuntimeClass() const; \

Take staticAfx_dataThe internal static object of the class declared by the hitting line. To export the class correctly and access runtime information from the executable file on the client, you must export this static object. Because static objects useAfx_dataModifier Declaration, so you only needAfx_dataDefined_ Declspec (dllexport)And when the client executable file is generatedAfx_dataDefined_ Declspec (dllimport). As we have defined this methodAfx_ext_classTherefore, you only need to refer to the class definitionAfx_dataRedefinesAfx_ext_classSame.

For example:


#undef  AFX_DATA
#define AFX_DATA AFX_EXT_CLASS

class CExampleView : public CView
{
DECLARE_DYNAMIC()
// ... class definition ...
};

#undef AFX_DATA
#define AFX_DATA

MFC is always used in the internal defined data items of its macroAfx_dataSymbol, so this technology applies to all such cases. For example, it appliesDeclare_message_map.

Use def File Import

If you select to use it with the. Def File_ Declspec (dllimport), You should change the. Def file and replace constant with data to reduce the possibility of problems caused by incorrect encoding:

// project.def
LIBRARY project
EXPORTS
ulDataInDll DATA

The following table describes the cause.

Keywords Issue in import/export warehouse Export

Constant

_ Imp_uldataindll_uldataindll

_ Uldataindll

Data

_ Imp_uldataindll

_ Uldataindll

Use_ Declspec (dllimport)And constant are listed at the same time in the. Lib DLL import library created to allow explicit linksIMPVersion and unmodified name. Use_ Declspec (dllimport)OnlyIMPVersion name.

If you use constant, you can use any of the following code to construct the accessUldataindll:

__declspec(dllimport) ULONG ulDataInDll; /*prototype*/
if (ulDataInDll == 0L) /*sample code fragment*/

-Or-

ULONG *ulDataInDll;      /*prototype*/
if (*ulDataInDll == 0L) /*sample code fragment*/

However, if data is used in the. Def file, only the Code Compiled using the following definition can be accessed.UldataindllVariable:

__declspec(dllimport) ULONG ulDataInDll;

if (ulDataInDll == 0L) /*sample code fragment*/

It is more risky to use constant, because if you forget to use an additional level of indirect addressing, the access may be a pointer to the import address table of the variable, rather than the variable itself. Since the import address table is currently set to read-only by the compiler and the linker, this type of problem is often caused by access conflicts.

If the current visual c ++ linker finds that constant in the. Def file is the cause of the above problem, it will issue a warning. The only real reason for using constant is: the incorrect file is not listed on the prototype._ Declspec (dllimport).

Use _ declspec (dllimport) to import data

For data, use_ Declspec (dllimport)Is a convenient way to remove the indirect layer. When importing data from a DLL, you still need to carefully check the import address table. In_ Declspec (dllimport)Previously, this means that when accessing the data exported from the DLL, you must remember to perform additional indirect addressing:

// project.h
#ifdef _DLL // If accessing the data from inside the DLL
ULONG ulDataInDll;

#else // If accessing the data from outside the DLL
ULONG *ulDataInDll;
#endif

Then export the data in the. Def file:

// project.def
LIBRARY project
EXPORTS
ulDataInDll CONSTANT

And access the data from the DLL:

if (*ulDataInDll == 0L) 
{
// Do stuff here
}

Mark data_ Declspec (dllimport)The compiler automatically generates indirect code for you. You do not have to worry about the above steps. As mentioned above, do not use the DLL in data generation_ Declspec (dllimport)Statement. The functions in the DLL do not use the imported address table to access data objects. Therefore, no additional indirect addressing is required.

__declspec(dllexport) ULONG ulDataInDLL;



Use _ declspec (dllimport) to import function calls

The following code example shows how to use_ Declspec (dllimport)Import a function call from a DLL to an application. Assume thatFunc1Is a function resident in a DLL, which is separated from the. exe file containing the "Main" function.

Not used_ Declspec (dllimport)The following code is provided:

int main(void) 
{
func1();
}

The compiler generates code similar to the following:

call func1

The linker translates the call into the following content:

call 0x4000000         ; The address of 'func1'.

IfFunc1In another DLL, the linker cannot parse this function directly because it cannot knowFunc1. In a 16-bit environment, the linker adds the Code address to a list in the. exe file, and the loader patches the list with the correct address during running. In 32-bit and 64-bit environments, the linker can generate a thunk that knows its address. In a 32-bit environment, Thunk is similar to the following:

0x40000000:    jmp DWORD PTR __imp_func1

Where,Imp_func1YesFunc1In the. exe file import address table. In this way, the linker knows all the addresses. To load a program, you only need to update the import address table of the. exe file during loading, and everything will work normally.

Therefore_ Declspec (dllimport)Better because the linker does not generate unnecessary thunks. Thunk makes the code larger (it may be a number of commands in the server Guard System) and reduces the cache performance. If the compiler function is notified to be In the DLL, the compiler will generate indirect calls for you.

Therefore, the Code is as follows:

__declspec(dllimport) void func1(void);
int main(void)
{
func1();
}

Generate this command:

call DWORD PTR __imp_func1

No thunk andJMPCommand, so the code is smaller and faster.

On the other hand, you do not need to use Indirect calls for function calls within the DLL. You already know the function address. Because time and space are required to load and store the function address before indirect calls, direct calls are always faster and the required space is always smaller. When calling a DLL from outside the DLL itself, you only want to use_ Declspec (dllimport). Do not use the internal functions of a DLL when generating a DLL._ Declspec (dllimport).



Use _ declspec (dllimport) to import data to an application.

If a program uses a DLL-defined public symbol, it means that the program is importing the public symbol. When creating a header file for an application generated using DLL_ Declspec (dllimport). Whether exported using the. Def file or_ Declspec (dllexport)Keyword export,_ Declspec (dllimport)All keywords are valid.

To improve code readability_ Declspec (dllimport)Define a macro and use this macro to declare each imported symbol:

#define DllImport   __declspec( dllimport )

DllImport int j;
DllImport void func();

Use in function declaration_ Declspec (dllimport)Is an optional operation, but if this keyword is used, the compiler will generate more effective code. However, to enable the imported executable file to access the public data symbols and objects of the DLL, you must use_ Declspec (dllimport). Note that the DLL user still needs to connect with the import/export link.

You can use the same header file for DLL and client applications. To do this, use a special Preprocessor symbol to indicate whether to generate a DLL or a client application. For example:

#ifdef _EXPORTING
#define CLASS_DECLSPEC __declspec(dllexport)
#else
#define CLASS_DECLSPEC __declspec(dllimport)
#endif

class CLASS_DECLSPEC CExampleA : public CObject
{ ... class definition ... };


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.