【发布时间】:2018-08-08 21:24:54
【问题描述】:
我知道混合来自不同 MSVC 的 DLL 是不好的,应该避免。 在这里,我想知道他们不同行为的原因。
背景:
附带第三方库(XXX.dll、XXX.lib 和 XXX.h) 我在我的应用程序中通过隐式链接使用它。 它们都是 x64。
- 我的应用程序是使用 MSVC 2015 构建的。
- 第 3 方 XXX.dll 显然是使用 MSVC 2008 构建的,并且
- 不幸的是,来自 XXX.dll 的函数调用涉及指针
- 例如
int __stdcall func1(const char * arg);将字符串作为参数 - 例如
int __stdcall func2(char * arg);获取由 DLL 填充的字符串
不同的设置:
在 Windows 7 (x64) 上
效果很好。
在 Windows 10 (x64) 上
由于读取无效的内存位置,我从 XXX.dll 收到访问冲突异常。 (即拨打int __stdcall func1(const char * arg);)
Exception thrown at 0x000001EF05A2BBB9 (XXX.dll) in Application.exe: 0xC0000005: Access violation reading location 0x00000000074A3A68.
(当有两个 CRT/Heap 并且指针传输不起作用时,这听起来很合理。)
问题:
为什么它可以在 Windows 7 上运行?
我使用相同的 MSVC2015 工具链并期望相同的行为。 或者有什么与操作系统相关的吗?
谢谢。
【问题讨论】:
-
如果 dll 暴露 C 接口并且不执行资源所有权转移,那么即使使用不同版本的编译器或完全不同的编译器构建,它也应该可以正常工作。简单地阅读
arg应该不会引起任何问题。您是否检查过调用堆栈以确定故障点是什么? -
这些都不是问题除非
func2最终释放了你给它的非常量字符串指针并且说-相同的指针做了不是源自对库的某些 other 调用。那你就麻烦了。无关的,找到作者并把他打得头晕目眩,因为他在没有指定大小约束的参数的情况下采用了“写入我的缓冲区”指针。这只是灾难的秘诀。从标准库中提取gets是有原因的。 -
可能,它更简单(与 DLL 和混合的 MSVC 运行时无关):在 Windows 7 上调用
func1()成功,但在 Windows 10 上失败(出于任何原因)。有人忘记检查func1()是否成功,因此在后一种情况下,连续处理返回值会崩溃。 (抱歉,如果我将func1()和func2()混合在一起,但我想你明白我的意思。) -
谢谢。一切都说得通。我正在尝试更深入地挖掘......并将很快更新
标签: c++ visual-studio dll windows-10