当(非托管)Win32程序(或其他DLL)调用(非托管)Win32 DLL时,我的理解是存在许多可能导致问题/崩溃的潜在不兼容性。
例如,如果程序P调用DLL D,而P是使用Visual Studio 2013编译为目标Windows SDK版本8,并且D编译为使用Visual Studio 2017来定位Windows SDK版本10,我的理解是他们将访问不同的msvc运行时DLL,可能会导致问题。例如,如果D使用new
分配内存并将其传递回P,并且P尝试delete
它,则会发生崩溃,因为P和D正在使用两个不同的运行时,每个运行时都维护自己的堆
类似地,如果P是使用运行时类型信息(RTTI)构建的而D不是,我的理解是,当P分配一个类实例(对于每个引用的类型)时,可能存在崩溃不兼容性。 .h文件)并将其传递给D,因为虚函数表和/或结构字段之间的填充不同。
我正在尝试了解可能存在的其他不兼容性。理想情况下,我想找到一个完整的清单。以下是一些可能的想法:
结构成员对齐(类似于RTTI问题)
使用多字节字符集与使用Unicode字符集(如果传递/返回字符串对象可能会导致问题?)
忽略(相对于不省略)帧指针(或者这可能不适用,因为跨程序/ DLL的函数调用机制不同于此标志关联的内部函数调用机制到?)
启用(或禁用)C ++异常(异常处理适用于DLL调用,如果它们都是在启用异常并使用相同的运行时构建的?)
其他
修改
我问这个问题是一般的好奇心,但也因为我在我的程序中使用DLL进行随机堆损坏,而我正试图弄清楚可能出现的问题。
我的问题原来是我正在链接一个过时的DLL导入库。我不确定为什么程序没有错误地启动,为什么它基本上运行正常但是间歇性堆损坏。我相信如果新的DLL提供旧DLL导入库提供的功能的超集,它只能无错误地启动。然后我不确定该机制是否与C / C ++运行时库不匹配,或者函数参数的变化可能没有功能签名的重大变化?
无论如何,我想可以将链接过时的DLL导入库添加到列表中,尽管它不像其他人提到的那样无辜。
答案 0 :(得分:2)
一个非常常见的错误是在dll- 接口中使用标准库内容或其他编译器实现/版本相关功能。 这通常仅在双方(dll及其用户)使用相同版本的编译器时才起作用,即使这样,当其中一个构建时启用了DEBUG而另一个构建了NDEBUG时,可能会出现不兼容。
仅在dll接口中使用c兼容类型等。