2015-11-04 39 views
0

我有一些用C語言編寫的代碼,並且有一個部分在使用Visual Studio 2015社區時拒絕合作(clang沒有問題)。我有一個簡單的結構:爲什麼MSVC不初始化這個const結構?

/** Options for enumerating over all documents. */ 
typedef struct { 
    unsigned   skip;  /**< The number of initial results to skip. */ 
    C4EnumeratorFlags flags; /**< Option flags */ 
} C4EnumeratorOptions; 

enum { 
    kC4Descending   = 0x01, /**< If true, iteration goes by descending document IDs. */ 
    kC4InclusiveStart  = 0x02, /**< If false, iteration starts just _after_ startDocID. */ 
    kC4InclusiveEnd   = 0x04, /**< If false, iteration stops just _before_ endDocID. */ 
    kC4IncludeDeleted  = 0x08, /**< If true, include deleted documents. */ 
    kC4IncludeNonConflicted = 0x10, /**< If false, include _only_ documents in conflict. */ 
    kC4IncludeBodies  = 0x20 /**< If false, document bodies will not be preloaded, just 
           metadata (docID, revID, sequence, flags.) This is faster if you 
           don't need to access the revision tree or revision bodies. You 
           can still access all the data of the document, but it will 
           trigger loading the document body from the database. */ 
}; 
typedef uint16_t C4EnumeratorFlags; 

而且我也有這方面的不斷的「默認」值:

// In header 
extern const C4EnumeratorOptions kC4DefaultEnumeratorOptions; 

// In implementation 
const C4EnumeratorOptions kC4DefaultEnumeratorOptions = { 
    0, // skip 
    kC4InclusiveStart | kC4InclusiveEnd | kC4IncludeNonConflicted | kC4IncludeBodies 
}; 

然而,當調試我注意到,初始化沒有做任何事情,當我嘗試使用默認值:

// options winds up with a "skip" value of something like 117939945 
// and a flags value of 59648 
C4EnumeratorOptions options = kC4DefaultEnumeratorOptions; 

定義的部分在DLL中,第二個使用在exe中。再次,這隻發生在Windows上。此外,「選項」中的值是垃圾,但由於某些原因,它甚至不是存儲在kC4DefaultEnumeratorOptions中的垃圾。我知道MSVC對於緩存C是臭名昭着的,但是這種初始化過時了,甚至MSVC也應該做到這一點,不是嗎?所以這一定是我正在做的事情,但我無法弄清楚什麼。

編輯符號通過導出定義文件導出。我用DUMPBIN檢查,發現該符號中導出的符號列表

41 46 00A6EA8 kC4DefaultEnumeratorOptions = kC4DefaultEnumeratorOptions

另外,作爲信息的一個以上位,調用代碼是C++和DLL的代碼是C,我懷疑這可能會在這個瘋狂中扮演一個角色。

+1

你怎麼知道它是「不能做什麼「? –

+0

它也看起來像你沒有導出符號。 [see here](http://stackoverflow.com/a/19374253/1505939) –

+0

@ M.M。那麼也許它正在做一些事情,但對我來說,價值看起來沒有初始化,因爲它是完全隨機的。我將檢查以確保該符號位於導出列表中(.def文件) – borrrden

回答

0

來自@ M.M的評論幫助我朝正確的方向發展。他問是否出口這個符號。從技術上講,是的,它出口後,因爲它在出口名單,但顯然我還需要出口的定義。因此,而不是包括在DEF文件的全局符號,我需要__declspec(dllexport)__declspec(dllimport)手動將其標記在兩個地方所以最後它看起來像這樣:

#ifdef _MSC_VER 
#ifdef CBFOREST_EXPORTS 
#define CBFOREST_API __declspec(dllexport) 
#else 
#define CBFOREST_API __declspec(dllimport) 
#endif 
#endif 

// ... 

// Header 
CBFOREST_API extern const C4EnumeratorOptions kC4DefaultEnumeratorOptions; 

// Implementation 
CBFOREST_API const C4EnumeratorOptions kC4DefaultEnumeratorOptions = { 
    0, // skip 
    kC4InclusiveStart | kC4InclusiveEnd | kC4IncludeNonConflicted | kC4IncludeBodies 
}; 
+0

這似乎不是C特定的,但僅限於Windows。你應該更新問題的標籤。 – Olaf

+0

@Olaf現在你提到它了,我沒有忘記提及這個代碼在其他地方都能正常工作--_-。我刪除了「c」標籤以避免混淆。 – borrrden