请教一个共享节的问题?

clxye 2009-07-06 11:45:47
我在一个对话框程序中设置了一个共享节,并设置了一个共享变量,但实际工作时好像有点问题,希望大家指点一下。


#pragma data_seg("Shared")
volatile int g_nInstance = 0;
#pragma data_seg()

#pragma comment(linker, "/SECTION:Shared, RWS")
...
...
BOOL CMy2Dlg::OnInitDialog()
{
CDialog::OnInitDialog();


// TODO: Add extra initialization here
g_nInstance++;

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


然后显示这个g_nInstance变量。

我期望的情况是,当运行这个程序时,程序的第一个实例中g_nInstance变量值应该为1。当不关闭这个程序,再运行一个这个程序实例时,此时的g_nInstance应该为2,但是实际情况仍然是1。也就是说g_nInstance变量并不是从第一个实例中获得的,不知为何?

谢谢!!
...全文
100 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
clxye 2009-07-06
  • 打赏
  • 举报
回复
嗯,谢谢各位。
我想各位高手都应该看过《Windows核心编程》吧,它里面举了一个例子,就是以SDD的exe文件为例的,这就令我困惑了。


下面是原文:

全局数据和静态数据不能被同一个. e x e或D L L文件的多个映像共享,这是个安全的默认设置。但是,在某些情况下,让一个. e x e文件的多个映像共享一个变量的实例是非常有用和方便的。例如,Wi n d o w s没有提供任何简便的方法来确定用户是否在运行应用程序的多个实例。但是,如果能够让所有实例共享单个全局变量,那么这个全局变量就能够反映正在运行的实例的数量。当用户启动应用程序的一个实例时,新实例的线程能够简单地查看全局变量的值(它已经被另一个实例更新);如果这个数量大于1,那么第二个实例就能够通知用户,该应用程序只有一个实例可以运行,而第二个实例将终止运行。

本节将介绍一种方法,它允许你共享. e x e或D L L文件的所有实例的变量。

清单17-1 AppInst示例应用程序


/******************************************************************************
Module: AppInst.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/


#include "..\CmnHdr.h" /* See Appendix A. */
#include <windowsx.h>
#include <tchar.h>
#include "Resource.h"


///////////////////////////////////////////////////////////////////////////////


// The system-wide unique window message
UINT g_uMsgAppInstCountUpdate = INVALID_ATOM;


///////////////////////////////////////////////////////////////////////////////


// Tell the compiler to put this initialized variable in its own Shared
// section so it is shared by all instances of this application.
#pragma data_seg("Shared")
volatile LONG g_lApplicationInstances = 0;
#pragma data_seg()

// Tell the linker to make the Shared section readable, writable, and shared.
#pragma comment(linker, "/Section:Shared,RWS")


///////////////////////////////////////////////////////////////////////////////


BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) {

chSETDLGICONS(hwnd, IDI_APPINST);

// Force the static control to be initialized correctly.
PostMessage(HWND_BROADCAST, g_uMsgAppInstCountUpdate, 0, 0);
return(TRUE);
}


///////////////////////////////////////////////////////////////////////////////


void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) {

switch (id) {
case IDCANCEL:
EndDialog(hwnd, id);
break;
}
}


///////////////////////////////////////////////////////////////////////////////


INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {

if (uMsg == g_uMsgAppInstCountUpdate) {
SetDlgItemInt(hwnd, IDC_COUNT, g_lApplicationInstances, FALSE);
}

switch (uMsg) {
chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);
chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand);
}
return(FALSE);
}


///////////////////////////////////////////////////////////////////////////////


int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) {

// Get the numeric value of the systemwide window message used to notify
// all top-level windows when the module's usage count has changed.
g_uMsgAppInstCountUpdate =
RegisterWindowMessage(TEXT("MsgAppInstCountUpdate"));

// There is another instance of this application running
InterlockedExchangeAdd((PLONG) &g_lApplicationInstances, 1);

DialogBox(hinstExe, MAKEINTRESOURCE(IDD_APPINST), NULL, Dlg_Proc);

// This instance of the application is terminating
InterlockedExchangeAdd((PLONG) &g_lApplicationInstances, -1);

// Have all other instances update their display
PostMessage(HWND_BROADCAST, g_uMsgAppInstCountUpdate, 0, 0);

return(0);
}


//////////////////////////////// End of File //////////////////////////////////

hgreminem 2009-07-06
  • 打赏
  • 举报
回复
上面的

#include "count.h"
#include <stdio.h>

应该换为

#include "Hook.h"
#include <stdio.h>

呵呵 复制的时候忘了改过来
用VC创建一个Dynamic Link Library工程
然后选择新建一个空工程
再把上面的文件代码添加到里面去就行了
百事烟 2009-07-06
  • 打赏
  • 举报
回复
此路不通,想别的办法,
DLL,INI文件,改别的算法
hgreminem 2009-07-06
  • 打赏
  • 举报
回复
应该把共享节放到DLL里
然后每次运行程序都自加1
下面是大概的代码:

count.cpp代码

#include "Hook.h"
#include <stdio.h>

#pragma data_seg(".myshare")
DWORD g_nInstance = 0;
#pragma data_seg()
#pragma comment(linker,"/SECTION:.myshare,RWS")

void RunningProc()
{
g_nInstance++;
}

DWORD GetCount()
{
return g_nInstance;
}


count.h代码

#ifndef _count_H
#define _count_H
#include <windows.h>
void RunningProc();
DWORD GetCount();
#endif


count.def代码

; count.def : Declares the module parameters for the DLL.

LIBRARY "count"
DESCRIPTION 'count Windows Dynamic Link Library'

EXPORTS
; Explicit exports can go here
RunningProc @1
GetCount @2


大概是这样吧 我是照着我的代码模板写的
没运行过 你试试看
yayafu 2009-07-06
  • 打赏
  • 举报
回复
exe没有共享内存,除非是dll.
yayafu 2009-07-06
  • 打赏
  • 举报
回复
但有一点可以肯定,Dll共享内存比exe容易得多.
yayafu 2009-07-06
  • 打赏
  • 举报
回复
那有特殊的编译开关吗?看过很久了,不记得了,回家研究研究哈哈

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧