类似于静态变量,
#pragma data_seg("name")
之后定义的变量,都会被作为是共享变量,所有调用该DLL的程序都可以使用,直到出现
#pragma data_seg()
STRLIB/strlib.h
#ifdef __cplusplus #define EXPORT extern "C" __declspec(dllexport) #else #define EXPORT extern __declspec(dllexport) #endif #define MAX_STRINGS 256 #define MAX_LENGTH 63 typedef BOOL (CALLBACK *GETSTRCB)(PCTSTR, PVOID); EXPORT BOOL CALLBACK AddStringA(PCSTR); EXPORT BOOL CALLBACK AddStringW(PCWSTR); EXPORT BOOL CALLBACK DeleteStringA(PCSTR); EXPORT BOOL CALLBACK DeleteStringW(PCWSTR); EXPORT BOOL CALLBACK GetStringsA(GETSTRCB, PVOID); EXPORT BOOL CALLBACK GetStringsW(GETSTRCB, PVOID); #ifdef UNICODE #define AddString AddStringW #define DeleteString DeleteStringW #define GetStrings GetStringsW #else #define AddString AddStringA #define DeleteString DeleteStringA #define GetStrings GetStringsA #endif
STRLIB/strlib.c
#include <windows.h> #include <wchar.h> #include "strlib.h" // 直到#pragma data_seg(),中间的变量是共享的 // 参数可以任意命名 // 共享的变量必须进行初始化 #pragma data_seg("shared") int iTotal = 0; WCHAR szStrings[MAX_STRINGS][MAX_LENGTH + 1] = {'\0'}; #pragma data_seg() // 提示编译器有一个叫做shared的段(section),权限是RWS(读写共享) #pragma comment(linker, "/SECTION:shared,RWS") int WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved) { return TRUE; } // 转换成宽字符串,调用AddStringW EXPORT BOOL CALLBACK AddStringA(PCSTR pStringIn) { BOOL bReturn; int iLength; PWSTR pWideStr; iLength = MultiByteToWideChar(CP_ACP, 0, pStringIn, -1, NULL, 0); pWideStr = malloc(iLength); MultiByteToWideChar(CP_ACP, 0, pStringIn, -1, pWideStr, iLength); bReturn = AddStringW(pWideStr); free(pWideStr); return bReturn; } EXPORT BOOL CALLBACK AddStringW(PCWSTR pStringIn) { PWSTR pString; int i, iLength; if (iTotal == MAX_STRINGS - 1) return FALSE; if ((iLength = wcslen(pStringIn)) == 0) return FALSE; pString = malloc(sizeof(WCHAR) * (1 + iLength)); wcscpy(pString, pStringIn); // 转大写 _wcsupr(pString); // 找到要插入的位置 for (i = iTotal; i > 0; i--) { if (wcscmp(pString, szStrings[i - 1]) >= 0) break; wcscpy(szStrings[i], szStrings[i - 1]); } wcscpy(szStrings[i], pString); iTotal++; free(pString); return TRUE; } // 转换成宽字符串,调用DeleteStringW EXPORT BOOL CALLBACK DeleteStringA(PCSTR pStringIn) { BOOL bReturn; int iLength; PWSTR pWideStr; iLength = MultiByteToWideChar(CP_ACP, 0, pStringIn, -1, NULL, 0); pWideStr = malloc(iLength); MultiByteToWideChar(CP_ACP, 0, pStringIn, -1, pWideStr, iLength); bReturn = DeleteStringW(pWideStr); free(pWideStr); return bReturn; } EXPORT BOOL CALLBACK DeleteStringW(PCWSTR pStringIn) { int i, j; if (0 == wcslen(pStringIn)) return FALSE; // 删除相等的第一个 for (i = 0; i < iTotal; i++) { if (_wcsicmp(szStrings[i], pStringIn) == 0) break; } if (i == iTotal) return FALSE; // 后面的字符串前移 for (j = i; j < iTotal; j++) wcscpy(szStrings[j], szStrings[j + 1]); szStrings[iTotal--][0] = '\0'; return TRUE; } EXPORT int CALLBACK GetStringsA(GETSTRCB pfnGetStrCallBack, PVOID pParam) { BOOL bReturn; int i, iLength; PSTR pAnsiStr; for (i = 0; i < iTotal; i++) { // 宽字符串转成多字节 iLength = WideCharToMultiByte(CP_ACP, 0, szStrings[i], -1, NULL, 0, NULL, NULL); pAnsiStr = malloc(iLength); WideCharToMultiByte(CP_ACP, 0, szStrings[i], -1, pAnsiStr, iLength, NULL, NULL); // 回调 bReturn = pfnGetStrCallBack(pAnsiStr, pParam); if (bReturn == FALSE) return i + 1; free(pAnsiStr); } return iTotal; } EXPORT int CALLBACK GetStringsW(GETSTRCB pfnGetStrCallBack, PVOID pParam) { BOOL bReturn; int i; for (i = 0; i < iTotal; i++) { bReturn = pfnGetStrCallBack(szStrings[i], pParam); if (bReturn == FALSE) return i + 1; } return iTotal; }
STRPROG/strprog.c
#include <Windows.h> #include "../STRLIB/strlib.h" #include "resource.h" typedef struct { HDC hdc; int xText; int yText; int xStart; int yStart; int xIncr; int yIncr; int xMax; int yMax; } CBPARAM; LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); TCHAR szAppName[] = TEXT("StrProg"); TCHAR szString[MAX_LENGTH + 1]; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrecInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = szAppName; wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, TEXT("DLL Demonstration Program"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: // 设置文本框最大可接受长度 SendDlgItemMessage(hDlg, IDC_STRING, EM_LIMITTEXT, MAX_LENGTH, 0); return TRUE; case WM_COMMAND: switch (wParam) { case IDOK: GetDlgItemText(hDlg, IDC_STRING, szString, MAX_LENGTH); EndDialog(hDlg, TRUE); return TRUE; case IDCANCEL: EndDialog(hDlg, FALSE); return FALSE; } } return FALSE; } // GetStrings回调,每个字符串都调用这个函数进行绘制 BOOL CALLBACK GetStrCallBack(PTSTR pString, CBPARAM *pcbp) { TextOut(pcbp->hdc, pcbp->xText, pcbp->yText, pString, lstrlen(pString)); if ((pcbp->yText += pcbp->yIncr) > pcbp->yMax) { pcbp->yText = pcbp->yStart; if ((pcbp->xText += pcbp->xIncr) > pcbp->xMax) return FALSE; } return TRUE; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HINSTANCE hInst; static int cxChar, cyChar, cxClient, cyClient; static UINT iDataChangeMsg; CBPARAM cbparam; HDC hdc; PAINTSTRUCT ps; TEXTMETRIC tm; switch (message) { case WM_CREATE: hInst = ((LPCREATESTRUCT)lParam)->hInstance; hdc = GetDC(hwnd); GetTextMetrics(hdc, &tm); cxChar = (int)tm.tmAveCharWidth; cyChar = (int)(tm.tmHeight + tm.tmExternalLeading); ReleaseDC(hwnd, hdc); // 注册消息,所有注册这个消息的窗口(过程)都能互相发送消息 iDataChangeMsg = RegisterWindowMessage(TEXT("StrProgDataChange")); return 0; case WM_COMMAND: switch (wParam) { case ID_ENTER: if (DialogBox(hInst, TEXT("EnterDlg"), hwnd, &DlgProc)) { if (AddString(szString)) // SendMessage效果相同,但是PostMessage不等待目标程序处理完成,而是直接返回 PostMessage(HWND_BROADCAST, iDataChangeMsg, 0, 0); else MessageBeep(0); } break; case ID_DELETE: if (DialogBox(hInst, TEXT("DeleteDlg"), hwnd, &DlgProc)) { if (DeleteString(szString)) PostMessage(HWND_BROADCAST, iDataChangeMsg, 0, 0); else MessageBeep(0); } break; } return 0; case WM_SIZE: cxClient = (int)LOWORD(lParam); cyClient = (int)HIWORD(lParam); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); cbparam.hdc = hdc; cbparam.xText = cbparam.xStart = cxChar; cbparam.yText = cbparam.yStart = cyChar; cbparam.xIncr = cxChar * MAX_LENGTH; cbparam.yIncr = cyChar; cbparam.xMax = cbparam.xIncr * (1 + cxClient / cbparam.xIncr); cbparam.yMax = cyChar * (cyClient / cyChar - 1); GetStrings((GETSTRCB)GetStrCallBack, (PVOID)&cbparam); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; default: // 收到广播的消息,刷新 if (message == iDataChangeMsg) InvalidateRect(hwnd, NULL, TRUE); break; } return DefWindowProc(hwnd, message, wParam, lParam); }
STRLIB/resource.h
//{{NO_DEPENDENCIES}} // Microsoft Visual C++ 生成的包含文件。 // 供 Resource.rc 使用 // #define IDC_STRING 1000 #define ID_ENTER 40001 #define ID_DELETE 40002 #define IDC_STATIC -1 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 101 #define _APS_NEXT_COMMAND_VALUE 40003 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif
STRPROG/Resource.rc
///////////////////////////////////////////////////////////////////////////// // // Dialog // ENTERDLG DIALOGEX 20, 20, 186, 47 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Enter" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "&Enter:", IDC_STATIC, 7, 7, 26, 9 EDITTEXT IDC_STRING, 31, 7, 148, 12, ES_AUTOHSCROLL DEFPUSHBUTTON "OK", IDOK, 32, 26, 50, 14 PUSHBUTTON "Cancel", IDCANCEL, 104, 26, 50, 14 END DELETEDLG DIALOGEX 20, 20, 186, 47 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Delete" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "&Delete:", IDC_STATIC, 7, 7, 26, 9 EDITTEXT IDC_STRING, 31, 7, 148, 12, ES_AUTOHSCROLL DEFPUSHBUTTON "OK", IDOK, 32, 26, 50, 14 PUSHBUTTON "Cancel", IDCANCEL, 104, 26, 50, 14 END ///////////////////////////////////////////////////////////////////////////// // // Menu // STRPROG MENU BEGIN MENUITEM "&Enter!", ID_ENTER MENUITEM "&Delete!", ID_DELETE END
欢迎转载,请保留出处与链接。Ocrosoft » [Win32]DLL共享内存