Chinaunix首页 | 论坛 | 博客
  • 博客访问: 303652
  • 博文数量: 50
  • 博客积分: 2855
  • 博客等级: 上尉
  • 技术积分: 353
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-08 13:43
文章分类

全部博文(50)

文章存档

2019年(1)

2016年(2)

2015年(6)

2014年(2)

2013年(4)

2012年(34)

2011年(1)

分类:

2012-11-24 08:33:23

原文地址:在DLL中导出变量 作者:bruceteen

用的是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在上下载。

阅读(4226) | 评论(3) | 转发(0) |
给主人留下些什么吧!~~

愚人陈2014-08-30 21:47:02

chensenwells:贴子没错,的确是导出了变量。
set,get只为了测试,是给读者看的,楼主已经说得很清楚了。
你可以把这个函数去掉,这个变量照样能访问,的确是导出了。

哦,谢谢, 我去试试~

回复 | 举报

chensenwells2013-09-11 17:29:17

愚人陈:Get,Set 相当于还是导出函数,
我还以为直接共享变量呢

不过还是谢谢

贴子没错,的确是导出了变量。
set,get只为了测试,是给读者看的,楼主已经说得很清楚了。
你可以把这个函数去掉,这个变量照样能访问,的确是导出了。

回复 | 举报

愚人陈2013-08-07 01:42:09

Get,Set 相当于还是导出函数,
我还以为直接共享变量呢

不过还是谢谢