升级Visual Studio后Fortran DLL出现异常



我有一个C++DLL。我们最初在Visual Studio 2005中开发了它,最近将它升级到了Visual Studio 2013。然后,此DLL调用Fortran DLL以实现某些功能(Fortran DLL由无法共享源代码的第三方开发人员提供)。最近,对于一些输入,对Fortran库的调用开始抛出一个异常:

First-chance exception at 0x1C00BA50 in Application.exe: 0xC0000005: Access violation executing location 0x1C00BA50.

仅当从Windows 7上Visual Studio 2013生成的可执行文件调用Fortran DLL时,才会发生此异常。当我用Visual Studio 2005可执行文件中的相同输入调用同一个Fortran DLL时,没有异常,Fortran DLL会产生正确的结果。此外,在Windows XP SP3上运行Visual Studio 2005解决方案也不会产生错误。

支持细节:

  • 调用Fortran的C++DLL是一个32位x86 DLL
  • Fortran DLL是针对DFort 6.1a构建的
  • 在依赖性walker中,需要:DFORRT.DLL、MSVCRT.DLL和KERNEL32.DLL
  • C++可执行文件是使用"Visual Studio 2013-Windows XP(v120_XP)"平台工具集为x86构建的
  • 崩溃不会发生在Windows XP SP3上;它在32位和64位Windows7机器上都可以。我正在设置一个Vista环境在那里进行测试,但几天内不会有结果

如果有帮助,函数签名是:

extern "C"
{
    typedef long (__stdcall *FUNCTIONID)
    (
    float* array1, 
    float* array2, 
    float* array3, 
    long& numItems, 
    long& numThings, 
    float* thingData, 
    float* thing2data,
    float& result, 
    long* resArray, 
    float* resArray2, 
    float* resArray3); 
}

库加载方式:

m_funcDLL = ::LoadLibrary("DLLNAME.DLL");

此外,我们称之为:

FUNCTIONID pfnFUNC = nullptr;
pfnFUNC = (FUNCTIONID)GetProcAddress(m_funcDLL, "FUNCNAME");
if(pfnFUNC) {
    try {
        iErr = (*pfnFUNC)( args...); 
    }
}

args是静态数组和动态数组的混合体(尽管我们已经用C++11的std::array和std::vector进行了实验来传递信息;使用这两种容器类型会得到相同的错误)。

我们在构建中没有使用Unicode(目前这是一个愿望列表项),所以我们使用多字节字符集(尽管传入的数组都不是字符数组)。

我的主要问题是:有人知道Windows 7上Visual Studio 2013的二进制兼容性问题会导致这样的崩溃吗?有没有我应该看的东西我没有?

如果发生以下一种或多种情况,链接到不同版本的运行库(可能还有其他库)的DLL和使用DLL的代码有被破坏的危险:

  • DLL的接口使用类/结构,其中的大小可能因运行库的版本而异。(一个不幸的成员可能就足够了)
  • 没有在接口的同一侧分配/释放堆对象
  • 有时人们会玩编译器关于对齐的设置。也许不同版本的编译器也会改变他们的"策略"
  • 注意#pragma(pack,..)、__declspec(align())等
  • 在VS的旧版本中,有"单线程"one_answers"多线程"版本的运行时库。混合使用未链接到同一类型库的DLL和应用程序可能会导致问题
  • 头文件中的#include <seeminglyharmlessheader.h>,应用程序和DLL都可以看到,可能会有一些令人讨厌的惊喜
  • 可能是其他编译器/链接器设置中的(未注意到的)更改,例如关于异常处理

我不能完全理解你在问题部分所说的32位/64位的内容。我不认为,混合这两种作品,但我也认为你没有尝试。

相关内容

最新更新