0

変数値の不可解な変化に直面しています。現在、私は C の経験があまりありません。ほとんどのコードは片手でキーボードを操作し、もう一方の手で K&R のページを追跡していました。

Visual Studio 2010 で、pupnp ライブラリの Lua バインディングである C プロジェクトがあります。関連するコードを次に示します。

ファイル: 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;
}

問題は次のとおりです。UPnPstartedstatic 変数は基本的に、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いるため、各翻訳までには独自の定義があります。.cUPnPStarted

これは、関数UpnpSendAdvertisement()が初めて呼び出されたときに、独自のバージョンの にアクセスしていることを意味します。このバージョンはUPnPStarted変更されておらず、変更されていない初期値の を持ちます0

翻訳単位間で同じ変数を共有するには、externat 宣言を使用し、定義を 1 つだけ指定します。

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

そして、1 つだけの.cファイルに次のように記述します。

volatile int UPnPStarted;
于 2013-01-23T09:01:22.527 に答える