0

我正面临变量值的莫名其妙的变化。现在我对C语言不是很熟悉,大部分代码我是一只手在键盘上写的,另一只手在K&R中跟踪一个页面,所以请温柔一点。

我在 Visual Studio 2010 中有一个 C 项目,它是 pupnp 库的 Lua 绑定。这是一些相关的代码;

文件:luaUPnPdefinitions.h(摘录)

#ifndef LuaUPnPdefinitions_h
#define LuaUPnPdefinitions_h
...
// tracker for library being started or not
volatile static int UPnPStarted;
...
#endif  /* LuaUPnPdefinitions_h */

文件:LuaUPnP.h(完整文件)

#ifndef LuaUPnP_h
#define LuaUPnP_h

#include "upnp.h"
#include "upnptools.h"
#include "uuid.h"
#include <lua.h>
#include <lauxlib.h>
#include "luaIXML.h"
#include "darksidesync_aux.h"
#include "luaUPnPdefinitions.h"
#include "luaUPnPsupport.h"
#include "luaUPnPcallback.h"

#endif  /* LuaUPnP_h */

文件:LuaUPnP.c(摘录)

#include "luaUPnP.h"  // only include in this file
...
static int L_UpnpSendAdvertisement(lua_State *L)
{
    int result = UpnpSendAdvertisement(checkdevice(L, 1), luaL_checkint(L,2));
    if (result != UPNP_E_SUCCESS) return pushUPnPerror(L, result, NULL);
    lua_pushinteger(L, 1);
    return 1;
}
...

文件:LuaUPnPsupport.h(摘录)

#ifndef LuaUPnPsupport_h
#define LuaUPnPsupport_h

//#include <ixml.h>
#include <lua.h>
#include <lauxlib.h>
#include "luaIXML.h"
#include "upnptools.h"
#include "luaUPnPdefinitions.h"
...
UpnpDevice_Handle checkdevice(lua_State *L, int idx);
...
#endif  /* LuaUPnPsupport_h */

文件:LuaUPnPsupport.c(摘录)

#include "luaUPnPsupport.h"  // only include in this file
...
UpnpDevice_Handle checkdevice(lua_State *L, int idx)
{
    pLuaDevice dev;
    luaL_checkudata(L, idx, LPNP_DEVICE_MT);
    if (! UPnPStarted) luaL_error(L, UpnpGetErrorMessage(UPNP_E_FINISH));
    dev = (pLuaDevice)lua_touserdata(L, idx);
    return dev->device;
}

现在解决问题;UPnPstarted静态变量基本上跟踪 pupnp 库后台进程是否已启动。L_UpnpSendAdvertisement现在当在某个点(可重现)调试函数时,然后UPnPstarted == 1,但是当我点击这条线时;

int result = UpnpSendAdvertisement(checkdevice(L, 1), luaL_checkint(L,2));

并进入它,调试器跳转到checkdevice函数(在文件 LuaUPnPsupport.c 中),并且值UPnPstarted立即更改为UPnPstarted == 0.

我迷路了。它是一个静态变量,所以应该共享,为什么它会改变值,只是通过进入另一个函数?在调试器中,监视窗口中的值以红色点亮,表示它们刚刚更改。最初我认为文件包含在错误的顺序中,并且UPnPstarted变量被重复(或有 2 个实例),但是在向监视窗口添加监视时;&UPnPstarted为了跟踪变量的内存位置,当我进入函数时没有看到变化,所以在我看来它指的是相同的内存位置。

我只是不明白。关于正在发生的事情有什么想法吗?

4

1 回答 1

1

将变量标记为static并不意味着将在翻译单元之间共享一个实例(本质上是一个.c源文件加上它提取的所有标题)。每个翻译直到都有自己的定义,UPnPStarted因为每个.c文件都包含定义的头文件UPnPStarted

这意味着当UpnpSendAdvertisement()第一次调用该函数时,它正在访问它自己的版本UPnPStarted,该版本没有被修改,并且将具有其初始的、未更改的值0

要跨翻译单元共享相同的变量,请使用externat 声明并提供一个定义:

/* In the header file. */
extern volatile int UPnPStarted;

然后在一个,而且只有一个.c文件中:

volatile int UPnPStarted;
于 2013-01-23T09:01:22.527 回答