【发布时间】:2014-04-27 05:51:19
【问题描述】:
我需要从依赖于一些全局静态变量的 C++ 代码构建 DLL 库。用户定义类的静态变量初始化得很好,而原始类型(int)的变量则没有。更有什者,试图改变这些变量的值会导致内存错误。我做错了什么?
我能够在几行示例中复制此错误,这是我的代码:
mylib.hpp
#include <string>
class AAA
{
public:
static int & get_static_int() { return static_int_; }
private:
static int static_int_;
};
mylib.cpp
#include "mylib.hpp"
#include <iostream>
int AAA::static_int_ = 42;
class BBB
{
public:
BBB() { std::cout << "BBB constructor!!!" << std::endl; };
};
static BBB b;
mylib.def:
LIBRARY mylib
EXPORTS
?static_int_@AAA@@0HA
main.cpp
#include <mylib.hpp>
#include <iostream>
int main()
{
std::cout << "get_static_int():" << AAA::get_static_int() << std::endl;
AAA::get_static_int() = 10; // Exception!
}
build.bat
cl /c mylib.cpp /I. /Fomylib.obj /MD /EHsc
link /MACHINE:X64 /dll mylib.obj /DEF:mylib.def /out:mylib.dll msvcrt.lib kernel32.lib oleaut32.lib
cl main.cpp mylib.lib /I. /EHsc /MD
输出:
>main
BBB constructor!!!
get_static_int():403973631
<windows complain>
我知道类似的问题:Loading DLL not initializing static C++ classes 并在链接选项中添加“-entry:_DllMainCRTStartup”并不能解决此问题。
我也知道在 C++ 中初始化单例的正确方法,但是对于这个项目,我需要移植相当大的 Linux 项目并且修改/重构它是不切实际的。
谢谢!
【问题讨论】:
-
您是否尝试过在没有 def 文件的情况下使用 dllexport 和 dllimport?
-
通过demangler.com 运行导出让我感谢该函数预计不会返回一个int&,而是一个int。 403973631是否可能是内存位置而不是值?
-
@cup 我试过使用 dllexport ,这确实解决了问题。但是我不能在我的项目中使用这个解决方案,因为它需要我修改原始代码库。知道如何创建正确的 def 文件吗?
-
@gha.st 我相信导出行正在为 static_int_ 变量指定导出,因此是正确的(函数本身是内联的)
-
在 Windows 上,您不能跨 DLL 边界使用 C++ 功能。您可以在程序中使用 C++,也可以在应用程序中使用 C++,但每个都有自己完全独立的 C++。这与 Linux 非常不同,Linux 有一个由所有模块共享的系统 C++ 运行时。如果您有一个带有 C++ API 的库,请使用静态链接。