使用 DLL 中的 C++ 函数的访问冲突
Access violation using a C++ function from a DLL
我有一个用 C++ 编写的游戏引擎,我正在将其移植到 Windows(来自 Mac)。它使用 C++11 和 OpenGL,并且出于所有意图和目的,它可以运行!
我正在为我的游戏引擎使用 DLL,它在运行时隐式链接到游戏 .exe
。问题是,当我尝试使用 DLL FileSystem
中的实用程序 class 来查找资源文件(纹理,但我认为它不重要)时,出现此错误:
First-chance exception at 0x00007FF9CF988830 (PocoFoundation64.dll) in TestEquinox.exe: 0xC0000005: Access violation reading location 0x000000136A4FF000.
当我从 DLL 中调用我的 FileSystem
class 的这个方法时,问题就来了(它被设计为采用 filename/partial 路径,它会在不同的地方查找完整的路径):
Poco::Path FileSystem::Get(const std::string &filename) {
std::vector<Poco::Path> paths = {
filename,
ResourceFolder() / filename //<<<<< ERROR HERE
};
for (const Poco::Path &path : paths) {
try {
if (Poco::File(path).exists()) {
return path;
}
} catch (...) { }
}
Logger("FileSystem", std::cerr) << "Could not find file '" << filename << "'!";
return {};
}
Visual Studio 将错误显示为调用 ResourceFolder()
,同一个 class 的另一个方法,也在 DLL 中。看起来是这样的:
Poco::Path FileSystem::ResourceFolder() {
Poco::Path userData;
//--SNIP-- (other OS's #ifdef'd here)
// GAME->StartupPath is a std::string containing the exe's parent folder
userData = (Poco::Path(GAME->StartupPath).parent() / "Resources").makeDirectory();
//--SNIP-- (and here)
try {
if (!Poco::File(userData).exists()) {
Poco::File(userData).createDirectories();
}
} catch (...) {}
return userData;
}
看来是Poco
的数据类型没有正确实例化?我使用所有相同的编译器设置(64 位、多字节字符集、VS2013)从源代码构建它,所以我不明白它怎么可能是名称 mangling/data 布局问题。
还有一点要注意 - 我将整个 FileSystem
class 从 DLL 复制到我的游戏项目 class 本地,称为 FileSystem2
。尽管是相同的代码,但使用相同的参数调用 FileSystem2::Get
工作正常且没有崩溃。
希望有人能指出我正确的方向?!
通常像这样的错误源于使用模块使用的不兼容的运行时库。请检查 Visual Studio 属性中所有模块的以下内容:
Project Properties -> C/C++ -> Code Generation -> Runtime Library
.
运行时设置(多线程 DLL、多线程调试 DLL 等)必须与您正在编译的所有模块匹配。如果它们不匹配,请选择一个运行时,并使用该运行时重建所有模块。
我有一个用 C++ 编写的游戏引擎,我正在将其移植到 Windows(来自 Mac)。它使用 C++11 和 OpenGL,并且出于所有意图和目的,它可以运行!
我正在为我的游戏引擎使用 DLL,它在运行时隐式链接到游戏 .exe
。问题是,当我尝试使用 DLL FileSystem
中的实用程序 class 来查找资源文件(纹理,但我认为它不重要)时,出现此错误:
First-chance exception at 0x00007FF9CF988830 (PocoFoundation64.dll) in TestEquinox.exe: 0xC0000005: Access violation reading location 0x000000136A4FF000.
当我从 DLL 中调用我的 FileSystem
class 的这个方法时,问题就来了(它被设计为采用 filename/partial 路径,它会在不同的地方查找完整的路径):
Poco::Path FileSystem::Get(const std::string &filename) {
std::vector<Poco::Path> paths = {
filename,
ResourceFolder() / filename //<<<<< ERROR HERE
};
for (const Poco::Path &path : paths) {
try {
if (Poco::File(path).exists()) {
return path;
}
} catch (...) { }
}
Logger("FileSystem", std::cerr) << "Could not find file '" << filename << "'!";
return {};
}
Visual Studio 将错误显示为调用 ResourceFolder()
,同一个 class 的另一个方法,也在 DLL 中。看起来是这样的:
Poco::Path FileSystem::ResourceFolder() {
Poco::Path userData;
//--SNIP-- (other OS's #ifdef'd here)
// GAME->StartupPath is a std::string containing the exe's parent folder
userData = (Poco::Path(GAME->StartupPath).parent() / "Resources").makeDirectory();
//--SNIP-- (and here)
try {
if (!Poco::File(userData).exists()) {
Poco::File(userData).createDirectories();
}
} catch (...) {}
return userData;
}
看来是Poco
的数据类型没有正确实例化?我使用所有相同的编译器设置(64 位、多字节字符集、VS2013)从源代码构建它,所以我不明白它怎么可能是名称 mangling/data 布局问题。
还有一点要注意 - 我将整个 FileSystem
class 从 DLL 复制到我的游戏项目 class 本地,称为 FileSystem2
。尽管是相同的代码,但使用相同的参数调用 FileSystem2::Get
工作正常且没有崩溃。
希望有人能指出我正确的方向?!
通常像这样的错误源于使用模块使用的不兼容的运行时库。请检查 Visual Studio 属性中所有模块的以下内容:
Project Properties -> C/C++ -> Code Generation -> Runtime Library
.
运行时设置(多线程 DLL、多线程调试 DLL 等)必须与您正在编译的所有模块匹配。如果它们不匹配,请选择一个运行时,并使用该运行时重建所有模块。