VC中.dll文件的编写
来源:互联网 发布:spring4源码分析 编辑:程序博客网 时间:2024/05/08 09:37
VC中.dll文件的编写
2008-05-03 15:19
①关于DLL的创建与调用
使用VC++的向导即可。具体操作如下:打开菜单“FileNew”→选择“ProjectsWin32 Dynamic-Link Library”→选择“A simple DLL project”即可。这时系统会自动生成3个文件:*.cpp,stdafx.cpp,stdafx.h。
之后将入口函数DLLMain()补充完整,再添加你自定义的函数的代码。如果你自定义的函数很多,可以将这些函数的声明部分统一写入一个头文件中。再在.cpp文件首部用“#include”语句引入这个头文件。注意函数声明前要加上“__declspec(dllexport)”。
(如果你建DLL时选择的是第三种类型(加入示例代码),则在函数声明及定义前都要加上系统定义的宏“*_API”。)
在VB中用如下语句声明:“Declare Function 函数名 Lib "完整路径文件名.dll" [Alias "函数别名"] (ByVal 变量1 As 类型1, ByVal 变量2 As 类型2,…) As 类型3”,与调用API函数类似。
注意:若在窗体代码的“通用”部分使用,“Declare”前要加“Private”;若在Moudle中使用,“Declare”前要加“Public”。若将DLL文件放在“WindowsSystem”或“WinNTSystem32”目录下,“Lib”后只写出DLL主文件名即可。
具体的实例代码见④(修正后的,可直接运行)。
②关于入口点
如上编写Cipher.dll,运行,出现错误信息“找不到DLL入口点(Error 53)”。出现这一错误的原因是C++编译器在编译时对函数名Encrypt作了修改。打开快速查看程序(D:WINNTSystem32ViewersQuikView.exe),将Cipher.dll拖入查看窗口,找到字段“?Encrypt@@YAHHH@Z”,发现函数名被加了一串字符。
解决方法有二。第一,直接在VB声明中将“?Encrypt@@Y AHHH@Z”作为别名放在“Alias”后即可;第二,在Cipher.dll代码中在语句“__declspec(dllexport) int __stdcall Encrypt(int p, int k); ”前加上“extern "C" ”,编译后,用QuikView查看,函数名变为“_Encrypt”,之后再在VB声明中做相应调整即可。
(对于使用宏的DLL,在“#define”语句中,对宏“Cipher_API”的替换值做更改即可。)
进行了③的更改后,程序又找不到入口点了。再用QuikView查看,发现函数名变为“_Encrypt@8”。还有解决方法。在Cipher.dll工程中添加一个文本文件,命名为“Cipher.def”,添加代码如④。编译后再用QuikView查看,函数名变回“Encrypt”,在VB中调用,运行正常。
③关于调用约定
采用②中第二种解决方法,运行,出现错误信息“DLL调用约定错误(Error 49)”。原因是调用约定共有4种方式:__fastcall、__pascal、__stdcall、__cdecl,VC++默认调用方式为__cdecl,而VB默认调用方式则为__stdcall。解决方法是,更改代码如下(限定调用方式):
extern “C” __declspec(dllexport) int __stdcall Encrypt(int p, int k);
…………
int __stdcall Encrypt(int p, int k)
{
int c = p+k;
return c;
}
④源代码
Cipher.dll:
Cipher.cpp:
//引入预编译头文件
#include “stdafx.h”
//声明我的函数
extern “C” __declspec(dllexport) int __stdcall Encrypt( int p, int k );
//DLL入口函数
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
//我的函数
int __stdcall Encrypt ( int p, int k )
{
int c = p + k ;
return c ;
}
Cipher.def:
LIBRARY Cipher
EXPORTS Encrypt
编译后,将Cipher.dll复制到“D:WINNTSystem32”目录。
在VB中调用:
Option Explicit
Private Declare Function Encrypt Lib “Cipher” _
(ByVal p As Long, ByVal k As Long) As Long
Private Sub Form_Load()
Dim c As Long
c = Encrypt(24, 8)
Text1.Text = c
End Sub
使用VC++的向导即可。具体操作如下:打开菜单“FileNew”→选择“ProjectsWin32 Dynamic-Link Library”→选择“A simple DLL project”即可。这时系统会自动生成3个文件:*.cpp,stdafx.cpp,stdafx.h。
之后将入口函数DLLMain()补充完整,再添加你自定义的函数的代码。如果你自定义的函数很多,可以将这些函数的声明部分统一写入一个头文件中。再在.cpp文件首部用“#include”语句引入这个头文件。注意函数声明前要加上“__declspec(dllexport)”。
(如果你建DLL时选择的是第三种类型(加入示例代码),则在函数声明及定义前都要加上系统定义的宏“*_API”。)
在VB中用如下语句声明:“Declare Function 函数名 Lib "完整路径文件名.dll" [Alias "函数别名"] (ByVal 变量1 As 类型1, ByVal 变量2 As 类型2,…) As 类型3”,与调用API函数类似。
注意:若在窗体代码的“通用”部分使用,“Declare”前要加“Private”;若在Moudle中使用,“Declare”前要加“Public”。若将DLL文件放在“WindowsSystem”或“WinNTSystem32”目录下,“Lib”后只写出DLL主文件名即可。
具体的实例代码见④(修正后的,可直接运行)。
②关于入口点
如上编写Cipher.dll,运行,出现错误信息“找不到DLL入口点(Error 53)”。出现这一错误的原因是C++编译器在编译时对函数名Encrypt作了修改。打开快速查看程序(D:WINNTSystem32ViewersQuikView.exe),将Cipher.dll拖入查看窗口,找到字段“?Encrypt@@YAHHH@Z”,发现函数名被加了一串字符。
解决方法有二。第一,直接在VB声明中将“?Encrypt@@Y AHHH@Z”作为别名放在“Alias”后即可;第二,在Cipher.dll代码中在语句“__declspec(dllexport) int __stdcall Encrypt(int p, int k); ”前加上“extern "C" ”,编译后,用QuikView查看,函数名变为“_Encrypt”,之后再在VB声明中做相应调整即可。
(对于使用宏的DLL,在“#define”语句中,对宏“Cipher_API”的替换值做更改即可。)
进行了③的更改后,程序又找不到入口点了。再用QuikView查看,发现函数名变为“_Encrypt@8”。还有解决方法。在Cipher.dll工程中添加一个文本文件,命名为“Cipher.def”,添加代码如④。编译后再用QuikView查看,函数名变回“Encrypt”,在VB中调用,运行正常。
③关于调用约定
采用②中第二种解决方法,运行,出现错误信息“DLL调用约定错误(Error 49)”。原因是调用约定共有4种方式:__fastcall、__pascal、__stdcall、__cdecl,VC++默认调用方式为__cdecl,而VB默认调用方式则为__stdcall。解决方法是,更改代码如下(限定调用方式):
extern “C” __declspec(dllexport) int __stdcall Encrypt(int p, int k);
…………
int __stdcall Encrypt(int p, int k)
{
int c = p+k;
return c;
}
④源代码
Cipher.dll:
Cipher.cpp:
//引入预编译头文件
#include “stdafx.h”
//声明我的函数
extern “C” __declspec(dllexport) int __stdcall Encrypt( int p, int k );
//DLL入口函数
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
//我的函数
int __stdcall Encrypt ( int p, int k )
{
int c = p + k ;
return c ;
}
Cipher.def:
LIBRARY Cipher
EXPORTS Encrypt
编译后,将Cipher.dll复制到“D:WINNTSystem32”目录。
在VB中调用:
Option Explicit
Private Declare Function Encrypt Lib “Cipher” _
(ByVal p As Long, ByVal k As Long) As Long
Private Sub Form_Load()
Dim c As Long
c = Encrypt(24, 8)
Text1.Text = c
End Sub
- VC中.dll文件的编写
- VC中.dll文件的编写
- 在C#.net中调用VC 6.0编写的DLL文件
- Silktest 调用 VC++ 编写的DLL文件
- vc编写Dll文件和调用的方法
- VC ++ 6.0 中 DLL文件的生成
- VC DLL的编写调用
- 在VC编写的DLL中导出C++类
- 在C#中调用VC编写的dll库
- 在C#中调用VC编写的dll库
- VC中编写Non MFC DLL的方法总结
- 在vb,vc中调用vb编写的DLL
- 在C#中调用VC编写的dll库
- Delphi中调用VC编写的DLL内对象
- 如何在VB中调用VC编写的DLL
- C#中调用VC编写的dll库
- VC中编写DLL的函数声明问题
- 在vb,vc中调用vb编写的DLL
- 工作与生活2
- 职场新人,如何抓住身边的贵人
- 数据库数据表交互信息
- 命令模式下的网络搜索: http://goosh.org/
- 投稿前的28个细节检查清单
- VC中.dll文件的编写
- 有很多电子书
- VC中.dll文件的编写
- 字符集编码问题研究
- 厚积薄发--我的文献阅读经验
- The 30 skills every IT person should have
- MOSS精英峰会2008暨群友见面会相关
- RMI远程调用实例
- 怎样回答辞职原因