S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

DLL共享变量

Posted on 2010-02-17 21:42 S.l.e!ep.¢% 阅读(650) 评论(0)  编辑 收藏 引用 所属分类: VC

//  The following ifdef block is the standard way of creating macros which make exporting 
//  from a DLL simpler. All files within this DLL are compiled with the TESTDLL_EXPORTS
//  symbol defined on the command line. this symbol should not be defined on any project
//  that uses this DLL. This way any other project whose source files include this file see 
//  TESTDLL_API functions as being imported from a DLL, wheras this DLL sees symbols
//  defined with this macro as being exported.
#ifdef TESTDLL_EXPORTS
#define  TESTDLL_API __declspec(dllexport)
#else
#define  TESTDLL_API __declspec(dllimport)
#endif

#pragma data_seg (
" .shared " )
int  g_TestValue  =   0 ;
#pragma data_seg ()

#pragma comment(linker, 
" /SECTION:.shared,RWS "


TESTDLL_API 
int  getTestValue( void );
TESTDLL_API 
void  setTestValue( int  nValue);



//  testDLL.cpp : Defines the entry point for the DLL application.
//

#include 
" stdafx.h "
#include 
" testDLL.h "

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;
}

//  This is an example of an exported function.
TESTDLL_API  int  getTestValue( void )
{
    
return  g_TestValue;
}

TESTDLL_API 
void  setTestValue( int  nValue)
{
    g_TestValue 
=  nValue;
}


EXPORTS
    getTestValue @
1
    setTestValue @
2


接下来,实践证明一下
BOOL CTestCallDLLDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

        
// 
    
    
// TODO: Add extra initialization here

    m_hModule 
= ::LoadLibrary("C:\\Documents and Settings\\Administrator\\桌面\\testDLL.dll");

    
    
return TRUE;  // return TRUE  unless you set the focus to a control
}

void CTestCallDLLDlg::OnButton1() 
{
    typedef 
int (*getTestValueType)(void);
    getTestValueType pfngetTestValue 
= (getTestValueType)::GetProcAddress(m_hModule, "getTestValue");

    
int i = pfngetTestValue();

    CString str;
    str.Format(
"The Value now is %d", i);
    AfxMessageBox(str);
}

void CTestCallDLLDlg::OnButton2() 
{
    typedef 
int (*getTestValueType)(void);
    getTestValueType pfngetTestValue 
= (getTestValueType)::GetProcAddress(m_hModule, "getTestValue");

    typedef 
void (*setTestValueType)(int nValue);
    setTestValueType pfnsetTestValue 
= (setTestValueType)::GetProcAddress(m_hModule, "setTestValue");

    
int i = pfngetTestValue() + 1;
    pfnsetTestValue(i);
    i 
= pfngetTestValue();

    CString str;
    str.Format(
"The Value now is %d", i);
    AfxMessageBox(str);    
}

奇迹般地,两个EXE拷到不同的地方,运行了两个实例,它们能够“数据共享”

加上下面两个功能:
void CTestCallDLLDlg::OnButton3() 
{
    ::FreeLibrary(m_hModule);
    m_hModule 
= NULL;
}

void CTestCallDLLDlg::OnButton4() 
{
    
// TODO: Add your control notification handler code here
    m_hModule = ::LoadLibrary("C:\\Documents and Settings\\Administrator\\桌面\\testDLL.dll");
}

就会发现,如果当所有EXE的实例都把 DLL 卸装再 Load 时,DLL的数据会清0.......

所以,为了“共享数据”,DLL必须至少有一个“引用(被某个EXE引用)”

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理