Building a DLL with Visual C++
来源:互联网 发布:淘宝论文代发 编辑:程序博客网 时间:2024/05/16 06:55
Building a DLL with Visual C++
Overview
Microsoft's Visual C++ (MSVC) integrated development environment (IDE) can be overwhelming if the programmer has never used it. This document is designed to aid those wanting to compile a DLL for use with LabVIEW.
Note: This document applies to MSVC 5.0 and 6.0.
Table of Contents
- Step 1: Creating a DLL Project
- Step 2: Editing the Source File
- Step 3: Exporting Symbols
- Step 4: Specifying the Calling Convention
- Step 5: Building the DLL
Step 1: Creating a DLL Project
Select File»New to open the New dialog box. On the Projects tab, select Win32 Dynamic-Link Library and then click OK.
In the next dialog box, select A simple DLL project and then click Finish.
MSVC creates a DLL project with one source (.cpp) file, which has the same name as the project. It also generates a stdafx.cpp file. The stdafx.cpp file is necessary, but you do not generally need to edit it.
Step 2: Editing the Source File
Every DLL file must have a DllMain function, which is the entry point for the library. Unless you must do a specific initialization of the library, the default DllMain that MSVC created is sufficient. Notice that this function does nothing.
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
return TRUE;
}
If a library initialization is required, you might need a more complete DllMain:
BOOL WINAPI DllMain(
HINSTANCEhinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved ) // reserved
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
}
return TRUE;
}
Once the DllMain function is complete, write the routines that you intend to access from the DLL.
//Function declarations
int GetSphereSAandVol(double radius, double* sa, double* vol);
double GetSA(double radius);
double GetVol(double radius);
...
int GetSphereSAandVol(double radius, double* sa, double* vol)
//Calculate the surface area and volume of a sphere with given radius
{
if(radius < 0)
return false; //return false (0) if radius is negative
*sa = GetSA(radius);
*vol = GetVol(radius);
return true;
}
double GetSA(double radius)
{
return 4 * M_PI * radius * radius;
}
double GetVol(double radius)
{
return 4.0/3.0 * M_PI * pow(radius, 3.0);
}
For the DLL to compile correctly, you must declare the pow function (i.e. power, pow(x,y) is equivalent to x^y) and the constant M_PI (i.e. 3.14159).
Do this by inserting two lines of code below #include "stdafx.h" at the top of the .cpp file. The code should look as follows:
#include "stdafx.h"
#include "math.h" //library that defines the pow function
#define M_PI 3.14159 //declare our M_PI constant
At this point, you can compile and link the DLL. However, if you do so, the DLL will not export any functions, and thus, will not really be useful.
Step 3: Exporting Symbols
To access the functions within the DLL, it is necessary to tell the compiler to export the desired symbols. However, you first must address the issue of C++ name decoration. MSVC compiles your source as C++ if it has a .cpp or .cxx extension. If the source file has a .c extension, then MSVC compiles it as C. If you compile your file as C++, then the function names are normally decorated in the output code. This might be problematic because the function name has extra characters added to it. To avoid this problem, declare the function as 'extern "C"' in the function declaration, as follows:
extern "C" int GetSphereSAandVol(double radius, double* sa, double* vol);
This prevents the compiler from decorating the name with C++ decorations.
When you finish with the C++ decorations, you can actually export the functions. There are two methods to inform the linker which functions to export. The first, and most simple, is to use the __declspec(dllexport) tag in the function prototype for any function you want to export. To do this, add the tag to the declaration and definition, as follows:
extern "C" __declspec(dllexport) int GetSphereSAandVol(double radius, double* sa, double* vol);
...
__declspec(dllexport) int GetSphereSAandVol(double radius, double* sa, double* vol)
{
...
}
The second method is to use a .def file to explicitly declare which functions to export. The .def file is a text file that contains information the linker uses to decide what to export. It has the following format:
LIBRARY <Name to use inside DLL>
DESCRIPTION "<Description>"
EXPORTS
<First export> @1
<Second export> @2
<Third export> @3
...
For the example DLL, the .def file will look like this:
LIBRARY EasyDLL
DESCRIPTION "Does some sphere stuff."
EXPORTS
GetSphereSAandVol @1
If you have properly created your DLL project, then the linker automatically looks for a .def file of the same name as the project in the project directory. To change this option, select Project»Settings. In the Link tab, specify Customize as the Category. In Project Options, modify the option that defaults to /def: ./<Your Project>.def.
See Also:
Microsoft's .DEF file method documentation
Step 4: Specifying the Calling Convention
The last thing that you might need to do before compiling the DLL is to specify the calling convention for the functions that you want to export. Usually, there are two choices: C calling convention or standard calling conventions, also called Pascal and WINAPI. Most DLL functions use standard calling conventions, but LabVIEW can call either.
To specify C calling conventions, you do not need to do anything. This is the default unless you specify otherwise in Project»Settings»C/C++»Code Generation. If you want to explicitly declare the function as a C call, use the __cdecl keyword in the function declaration and definition:
extern "C" __declspec(dllexport) int __cdecl GetSphereSAandVol(double radius, double* sa, double* vol);
...
__declspec(dllexport) int __cdecl GetSphereSAandVol(doublt radius, double* sa, double* vol)
{
...
}
To specify standard calling conventions, place the __stdcall keyword in the function declaration and definition:
extern "C" int __stdcall GetSphereSAandVol(double radius, double* sa, double* vol);
...
int __stdcall GetSphereSAandVol(doublt radius, double* sa, double* vol)
{
...
}
When using standard calling conventions, the function name is decorated in the DLL. You can avoid this by using the .def file method of exporting functions, rather than the __declspec(dllexport) method. Therefore, National Instruments recommends that you use the .def file method to export stdcall functions.
Step 5: Building the DLL
Once you write the code, declare what functions to export, and set the calling conventions, you are ready to build your DLL. Select Build»Build <Your project> to compile and link your DLL. You are now ready to use or debug your DLL from LabVIEW. The attached EasyDLL.zip file contains the Visual C++ workspace used to create this DLL and a LabVIEW VI that accesses the DLL.
Downloads
easydll.zip
- Building a DLL with Visual C++
- Creating a Windows DLL with Visual Basic
- Building a Web Site with Ajax: Visual QuickProject Guide
- Building a Visual Robot Model with URDF from Scratch
- How to compile a C/C++ DLL for 64 bit with Visual Studio?
- visual studio编译:fatal error C1189: #error : Building MFC application with /MD[d] (CRT dll version)
- Building Automated Trading Systems: With an Introduction to Visual C++.NET 2005
- Building SQLite3 with Visual Studio 2005
- Building QT 4 with Visual C++ 2005
- Building Mongodb with Visual Studio 2008
- Building OpenCV with Visual Studio 2015
- Building Mongodb with Visual Studio 2008
- Building a Dynamic UI with Fragments - Building a Flexible UI
- Building a Simple Search Engine with C#
- Building a Drum Machine with DirectSound.
- Building a Monitoring Infrastructure with Nagios
- Building a Server with FreeBSD 7 [ILLUSTRATED]
- Compiling and building a project with rebar
- 新手该学什么编程语言
- 半小时学会正则表达式(一)
- 使用Windows Live Writer发布的第一篇日志
- DELPHI调用vc++DLL之灵异现象
- XEN虚拟化技术概论
- Building a DLL with Visual C++
- 【其他】【RQNOJ】三元组
- IO:2038
- ZJUT_OJ1190
- 半小时学会正则表达式(二)
- 同步Windows Mobile SIM卡联系人
- 老手是这样教新手编程的
- mini2440按键中断和LED gpio
- Hibernate.cfg.xml配置分析讲解