DLL共享变量


//  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引用)”

你可能感兴趣的:(DLL共享变量)