我有一些用C编写的代码,并且有一个部分在使用Visual Studio 2015社区时拒绝合作(clang没有问题)。我有一个简单的结构:
/** 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;
我也有一个常数&#34;默认&#34;它的价值:
// 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上。此外,&#34;选项中的值&#34;是垃圾,但由于某种原因,它甚至不是kC4DefaultEnumeratorOptions
中存储的垃圾。我知道MSVC因缓冲C而臭名昭着,但这种初始化是如此之久以至于即使MSVC也应该做对,不应该这样做吗?所以它一定是我正在做的事情,但我无法弄清楚是什么。
编辑通过导出定义文件导出符号。我检查了dumpbin,并在导出的符号列表中找到了符号
41 46 00A6EA8 kC4DefaultEnumeratorOptions = kC4DefaultEnumeratorOptions
另外,作为一点信息,调用代码是C ++,DLL代码是C,我怀疑这可能是这种疯狂的一部分。
答案 0 :(得分: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
};