一步一步教用VC和VB调用C++ DLL.docx
- 文档编号:26955615
- 上传时间:2023-06-24
- 格式:DOCX
- 页数:11
- 大小:781.48KB
一步一步教用VC和VB调用C++ DLL.docx
《一步一步教用VC和VB调用C++ DLL.docx》由会员分享,可在线阅读,更多相关《一步一步教用VC和VB调用C++ DLL.docx(11页珍藏版)》请在冰豆网上搜索。
一步一步教用VC和VB调用C++DLL
一步一步教你用VC和VB调用C++DLL
从VC++应用程序调用C++DLL的函数
VisualStudio6使创建包含函数或类的动态连接库(DLL)变得非常容易.
第一步
打开VisualStudio然后选择File|New菜单项:
选择Win32DynamicLinkLibrary,输入工程名,敲OK.
选择ADLLthatexportssomesymbols并单击Finish.在FileView里你会看到如下的工程文件:
第二步
在Test.cpp里,你将看到如下代码:
//Test.cpp:
DefinestheentrypointfortheDLLapplication.//#include"stdafx.h"#include"Test.h"
BOOLAPIENTRYDllMain(HANDLEhModule,
DWORD ul_reason_for_call,
LPVOIDlpReserved)
{
switch(ul_reason_for_call)
{
caseDLL_PROCESS_ATTACH:
caseDLL_THREAD_ATTACH:
caseDLL_THREAD_DETACH:
caseDLL_PROCESS_DETACH:
break;
}
returnTRUE;
}
//Thisisanexampleofanexportedvariable
TEST_APIintnTest=0;
//Thisisanexampleofanexportedfunction.
TEST_APIintfnTest(void)
{
return42;
}
//Thisistheconstructorofaclassthathasbeenexported.//seeTest.hfortheclassdefinition
CTest:
:
CTest()
{
return;
}
Test.cpp包含了fnTest和CTest:
:
CTest.如果你现在编译Test.dll,你将会得到一个可以被其他VC++应用程序直接调用的DLL.允许其他VC++程序调用的关键机制?
(keymechanism)就包含在Test.h中:
//Thefollowingifdefblockisthestandardwayofcreatingmacros//whichmakeexportingfromaDLLsimpler.AllfileswithinthisDLL//arecompiledwiththeTEST_EXPORTSsymboldefinedonthecommandline.//ThissymbolshouldnotbedefinedonanyprojectthatusesthisDLL.//Thiswayanyotherprojectwhosesourcefilesincludethisfilesee//TEST_APIfunctionsasbeingimportedfromaDLL,whereasthisDLL//seessymbolsdefinedwiththismacroasbeingexported.#ifdefTEST_EXPORTS#defineTEST_API__declspec(dllexport)#else#defineTEST_API__declspec(dllimport)#endif//ThisclassisexportedfromtheTest.dll
共4页 第1页 第2页 第3页 第4页
classTEST_APICTest
{
public:
CTest(void);
//TODO:
addyourmethodshere.
};
externTEST_APIintnTest;
TEST_APIintfnTest(void);
这里面发生了什么?
#ifdefTEST_EXPORTS是什么意思?
TEST_EXPORTS又是在哪定义的?
TEST_EXPORTS如果被定义,那么TEST_API将会被定义为__declspec(dllexport)(DLL导出),否则,将会被定义为__declspec(dllimport)(DLL导入).这将影响到后边定义的Ctest类是导出类还是导入类.这意味着如果我们需要导出的时候,我们就得定义TEST_EXPORTS.当一个VC++应用程序要访问这个DLL的时候,可以将Test.lib链接进去,它包含了DLL的导出符号.
第三步
TEST_EXPORTS在哪里被定义了呢?
DLLwizard干了一件我讨厌的事,它把TEST_EXPORTS放到了命令行里.选择Project|Settings|C/C++|General,你将看到工程选项:
当然了,这个办法是可行的.但是它却容易让人忽计,并且可能导致维护上的麻烦.我比较喜欢清楚明白的定义TEST_EXPORTS:
从项目选项里边去掉/D"TEST_EXPORTS",然后在Test.cpp里来定义它:
//Test.cpp:
DefinestheentrypointfortheDLLapplication.
//
#include"stdafx.h"
#defineTEST_EXPORTS //<=== ADDTHISLINE
#include"Test.h"
BOOLAPIENTRYDllMain(HANDLEhModule,
DWORD ul_reason_for_call,
LPVOIDlpReserved)
{
.
.
.
注意#defineTEST_EXPORTS在#include"Test.h"前边.所以,它定义要在头文件里.现在,可以像先前那样重新编译我们的Test.dll,我们将得到一个可以被其他VC应用程序所调用的DLL.
第四步
我们如何调用DLL里的函数呢?
举个例子吧,我用VS创建一个示例.选MFCAppWizard(exe),输入项目名字,然后点OK.选择基于对话框.然后点Finish.打开XXXDlg.cpp(XXX是你的工程名字.)找到OnInitDialog()成员函数,敲进去如下的代码:
.
.
.
//Settheiconforthisdialog. Theframeworkdoesthisautomatically
// whentheapplication'smainwindowisnotadialog
SetIcon(m_hIcon,TRUE); //Setbigicon
SetIcon(m_hIcon,FALSE); //Setsmallicon
//codetotestTest.dllfunction:
intn=fnTest(); //<===ADDTHISLINE
//codetotesttheCTestclass:
CTesttest;
//<===ADDTHISLINE
returnTRUE; //returnTRUE unlessyousetthefocustoacontrol
}
第五步
我们还没写完代码呢,现在要把Test.h这个DLL的头文件包含进去:
//TestExeDlg.cpp:
implementationfile//#include"stdafx.h"#include"TestExe.h"#include"TestExeDlg.h"#include"Test.h" //<===ADDTHISLINE
.
.
.
第六步
如果你想赶时间做一个演示的话,你可能会尝试只是拷贝DLL的test.h到你的项目目录里去,那么编译器会找到它.但是当项目很大的时候,这可不是个好主意,因为当你更新你的DLL文件时,可能会遇上危险.比如忘了拷贝它到你的exe的目录中去.这里有个简单的方法来解决这个问题:
选择Project|Settings|C/C++|Settings|Preprocessor,并且添加Additionalincludedirectories:
(DLL工程的目录)
提示这样做实际上是假设DLL项目和EXE项目拥有同一个项目目录.
现在当我编译的时候,我得到了一个linkererrors!
!
Deletingintermediatefilesandoutputfilesforproject'TestExe-Win32Debug'.
--------------------Configuration:
TestExe-Win32Debug--------------------
Compilingresources...
Compiling...
StdAfx.cpp
Compiling...
TestExe.cpp
TestExeDlg.cpp
GeneratingCode...
Linking...
TestExeDlg.obj:
errorLNK2001:
unresolvedexternalsymbol"__declspec(dllimport)
public:
__thiscallCTest:
:
CTest(void)"(__imp_?
?
0CTest@@QAE@XZ)
TestExeDlg.obj:
errorLNK2001:
unresolvedexternalsymbol"__declspec(dllimport)
int__cdeclfnTest(void)"(__imp_?
fnTest@@YAHXZ)
Debug/TestExe.exe:
fatalerrorLNK1120:
2unresolvedexternals
Errorexecutinglink.exe.
TestExe.exe-3error(s),0warning(s)
第七步
虽然我已经告诉编译器DLL符号啦,但是链接器还不知道.所以我们必须告诉链接器..选择Project|Settings|Link,把DLL的lib文件加到Object/librarymodules里边去:
----------------------------------------------
第八步
好啦,现在编译通过.在我们运行程序前,别忘了一件事:
把Test.dll拷贝到EXE的目录里去.
第九步
接下来,可以放一个断点到OnInitDialog()函数里去,点GO(F5)调试运行:
可以看到,fnTest返回了42,和我们预测的一样.CTest类也可以用类似的方法来测试.
要点.
∙VS的工程向导为我们创建VC++DLL提供了很好的开始.
∙函数,类,和变量可以从DLL中导出.
∙使用#define预处理器定义,一个头文件将可以被DLL和应用程序共同使用.
∙DLL导出它的符号,并且应用程序导入这个DLL符号.当编译应用程序时,编译器通过头文件看到的DLL符号,当链接应用程序时,链接器通过导入库(Test.lib)看到DLL符号.
∙当执行应用程序时,DLL必须放到和EXE相同的目录中去.DLL也可以放到windows或者system目录中,这样也是可行的,但是它经常引起某些问题,所以应该避免这样使用
和exe文件.如果这样做的话,我们怎么告诉链接器找到lib文件呢?
有两种方法来做:
1.选择Tools|Options|DirectoriesandsetShowdirectoriesfor为"Libraryfiles".在下边添加上我们工程所使用的Lib文件的路径.
1.2.另一种办法是,选择Project|Settings|Link,选category为Input,在下边的Additionallibrarypath筐里输入工程使用的lib文件的所在路径.
哪种方法更好一点呢?
这取决于你的开发环境.第一种方法要求整个工程要共享的设置目录路径,并且所有要求所有的开发者的VS都必须设置到这些路径.
第二种方法允许每个工程定制自己的路径,并且在工程中被储存,如果开发者的计算机上存放了同样的目录,那么每个开发者都可以签出工程并且设计.,这样可以避免在每台机器上都去设置同样的路径.
到现在,我还没有说怎样指定要使用的LIB文件,我的办法是在DLL的Test.h中添加两行,现在它看起来像下边的样子:
#ifdefTEST_EXPORTS #defineTEST_API__declspec(dllexport)#else #defineTEST_API__declspec(dllimport) #pragmamessage("automaticlinktoTest.lib") //<==addthisline #pragmacomment(lib,"Test.lib") //<==addthisline#endif//ThisclassisexportedfromtheTest.dllclassTEST_APICTest
{
public:
CTest(void);
};
externTEST_APIintnTest;
TEST_APIintfnTest(void);
这样做,保证了当工程包含DLL的头文件时,它会自动的把DLL的lib链接进去,我们可以从VS的OUTPUT窗口看到#pragmamessage给我们的传达的"automaticlinktoTest.lib"这个消息.
(PS:
原文在这里
demo也可以在这里下载到
)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 一步一步教用VC和VB调用C+ DLL 一步一步 VC VB 调用 C+