2012年(158)
分类: C/C++
2012-11-23 17:46:58
用的是VC2005
创建一个Win32 Project,在向导页勾选“DLL”和“Empty
project”,添加两个文件
1. win32dll.cpp,内容是
__declspec(dllexport) int AAA;
extern "C" __declspec(dllexport) int __stdcall GetAAA()
{
return
AAA;
}
extern "C" __declspec(dllexport) void __stdcall SetAAA( int aaa )
{
AAA = aaa;
}
其中 GetAAA/SetAAA 只是用于测试
2. win32dll.def,内容是
LIBRARY win32dll
EXPORTS
AAA @1 DATA
GetAAA @2
SetAAA @3
打开工程属性页 configuration properties->Linker->Input->Module
Definition File输入win32dll.def (VC6等不需要这一步)
编译连接就得到
win32dll.dll、win32dll.lib 等等
创建一个空的控制台程序,添加一个文件,内容是
#include
// 方法1,使用隐式调用
#pragma comment( lib,
"E:\\test\\cpp09\\Debug_ansi\\win32dll.lib" )
extern __declspec(dllimport)
int AAA;
extern "C" __declspec(dllimport) int __stdcall GetAAA();
extern
"C" __declspec(dllimport) void __stdcall SetAAA( int aaa );
void
foo1()
{
AAA = 123;
std::cout << GetAAA() <<
std::endl;
SetAAA( 456 );
std::cout << AAA << std::endl;
}
// 方法2,使用显式调用
#include
void foo2()
{
HMODULE a = LoadLibraryA( "E:\\test\\cpp09\\Debug_ansi\\win32dll.dll" );
if( a )
{
int* pAAA = (int*)GetProcAddress( a, "AAA"
);
int (__stdcall *pGetAAA)() = ( int (__stdcall*)() )GetProcAddress(
a, "GetAAA" );
void (__stdcall *pSetAAA)(int) = ( void
(__stdcall*)(int) )GetProcAddress( a, "SetAAA" );
if( pAAA && pGetAAA && pSetAAA )
{
*pAAA = 123;
std::cout << pGetAAA()
<< std::endl;
pSetAAA( 456 );
std::cout << *pAAA <<
std::endl;
}
FreeLibrary( a );
}
}
int main()
{
foo1();
foo2();
return 0;
}
将win32dll.dll、win32dll.lib
等拷贝到第二个程序下,就可以运行了。
----------------------------------------------------------------------------------------
假如不使用def文件,对于“隐式调用”丝毫不影响;对于“显式调用”,要改为
int* pAAA = (int*)GetProcAddress( a, "?AAA@@3HA"
);
int (__stdcall *pGetAAA)() = ( int (__stdcall*)() )GetProcAddress(
a, "_GetAAA@0" );
void (__stdcall
*pSetAAA)(int) = ( void (__stdcall*)(int) )GetProcAddress( a, "_SetAAA@4"
);
这些符号可以通过depends.exe打开相应的dll来查看,depends.exe在上下载。