近日寫程序,讓全局共享變量給害苦了,現將結果公布出來,不希望有人步我後塵。
先總結經驗:全局共享變量一定要在定義時初始化,否則無效。
下面寫兩行代碼進行驗證(Visual Studio .NET 2003 + Windows Servers 2003):
////////////////////////////
//main.c
#include
#include "resource.h"
__declspec(dllexport) void Test(HWND hWnd);
//主窗體回調函數
LRESULT CALLBACK MainProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM
lParam)
{
switch(message)
{
case WM_COMMAND:
{
if(LOWORD(wParam)==IDOK)
{
Test(hWnd);
return 1;
}
else if(LOWORD(wParam)== IDCANCEL)
{
EndDialog(hWnd,0);
return 1;
}
}
}
return 0;
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
DialogBox(hInstance,ID_DLG,NULL,MainProc);
return 0;
}
///////////////////////////////////////
//dll.c
#include
#include
//定義全局共享變量
#pragma data_seg(".Shared")
static int haveinit=0;//初始化
static int noinit; //未初始化
#pragma data_seg()
#pragma comment(linker, "/section:.Shared,rws")
__declspec(dllexport) LRESULT CALLBACK TestProc(int code, WPARAM
wParam, LPARAM lParam)
{
if (code >= 0)
{
CWPSTRUCT *msg = (CWPSTRUCT *) lParam;
if (msg->message==WM_NULL)
{
char Text[50];
//進行付值
haveinit=100;
noinit=100;
sprintf(Text,"haveinit=%d\nnoinit=%d",haveinit,noinit);
MessageBox((HWND)msg->wParam,Text,"付值情況",MB_OK);
}
}
return CallNextHookEx(NULL, code, wParam, lParam);
}
__declspec(dllexport) void Test(HWND hWnd)
{
char Text[50];
//尋找任意對話框
HWND hTest=FindWindow("#32770","");
//取得對話框的線程句柄
HWND handle=GetWindowThreadProcessId(hTest,NULL);
HANDLE hLib= GetModuleHandle("dll.dll");
//添加鉤子
HHOOK hook = SetWindowsHookEx(WH_CALLWNDPROC,TestProc,hLib ,handle);
if(hook)
{
//發送消息激活鉤子
SendMessage(hTest,WM_NULL,(WPARAM)hWnd,0);
//卸載鉤子
UnhookWindowsHookEx(hook);
//輸出結果
sprintf(Text,"haveinit=%d\nnoinit=%d",haveinit,noinit);
MessageBox(hWnd,Text,"輸出結果",MB_OK);
}
}
/////////////////////////////////////////////////////
//res.rc
/////////////////////////////////////////////////////
//
// Dialog
//
ID_DLG DIALOGEX 0, 0, 186, 90
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER |
WS_POPUP |
WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "測試",IDOK,26,25,50,14
PUSHBUTTON "關閉",IDCANCEL,99,26,50,14
END
///////////////////////////////////////
//resource.h
#define ID_DLG 101
將上面的dll.c編譯成dll文件,main.c編譯成exe文件,程序運行結果便可以說明一切。