从Fortran调用Delphi函数时出现分段错误

从Fortran调用Delphi函数时出现分段错误,delphi,windows-7,32bit-64bit,gfortran,Delphi,Windows 7,32bit 64bit,Gfortran,我有一个Fortran 90程序,它反复调用Delphi函数。函数被调用了很多次,但最终程序因分段错误而退出 我有一个用ibmfortran编译的代码的可执行文件,它工作得很好,我必须用gfortran重新编译整个代码 我有主程序的源代码,但没有函数的源代码,它位于随代码提供的DLL中,还有一个boreland DLL,它可能支持Delphi位:borlndmm.DLL DLL是32位的,我使用的是windows 7系统,带有32位gfortran编译器,规格如下: COLLECT_GCC=C:

我有一个Fortran 90程序,它反复调用Delphi函数。函数被调用了很多次,但最终程序因分段错误而退出

我有一个用ibmfortran编译的代码的可执行文件,它工作得很好,我必须用gfortran重新编译整个代码

我有主程序的源代码,但没有函数的源代码,它位于随代码提供的DLL中,还有一个boreland DLL,它可能支持Delphi位:borlndmm.DLL

DLL是32位的,我使用的是windows 7系统,带有32位gfortran编译器,规格如下:

COLLECT_GCC=C:\program files (x86)\gcc\bin\gfortran.exe COLLECT_LTO_WRAPPER=c:/program files (x86)/gcc/bin/../libexec/gcc/i686-pc-mingw32/4.7.2/lto-wrapper.exe Target: i686-pc-mingw32 Configured with: ../gcc-4.7.2-mingw/configure --host=i686-pc-mingw32 --build=x86_64-unknown-linux-gnu --target=i686-pc-mi ngw32 --prefix=/home/gfortran/gcc-home/binary/mingw32/native/x86_32/gcc/4.7.2 --with-gcc --with-gnu-as --with-gnu-ld --wi th-cloog=/home/gfortran/gcc-home/binary/mingw32/native/x86_32/cloog --with-gmp=/home/gfortran/gcc-home/binary/mingw32/nat ive/x86_32/gmp --with-mpfr=/home/gfortran/gcc-home/binary/mingw32/native/x86_32/mpfr --with-mpc=/home/gfortran/gcc-home/b inary/mingw32/native/x86_32/mpc --enable-cloog-backend=ppl --with-sysroot=/home/gfortran/gcc-home/binary/mingw32/cross/x8 6_32/gcc/4.7.2 --disable-shared --disable-nls --disable-tls --disable-win32-registry --enable-libquadmath-support --enabl e-libquadmath --enable-languages=c,c++,fortran --enable-libgomp --enable-threads=win32 --enable-lto --enable-static --ena ble-shared=lto-plugin --enable-plugins --with-host-libstdcxx='-lstdc++ -lsupc++ -lm' --with-ppl=/home/gfortran/gcc-home/b inary/mingw32/native/x86_32/ppl --enable-ld=yes Thread model: win32 gcc version 4.7.2 (GCC) 我已经翻译成:

INTERFACE
 LOGICAL (C_BOOL) FUNCTION CluesOvr(scenario,region,soilorder,topography,rainfall, &
    ASoildepth,Snumdairy,Snumsheep,Snumbeef,Snumdeer,AdditionalNitrogen, &
    Supplementrate, SupplementType,Nloss,Ploss, &
    ErrStr) BIND (C, name='CluesOvr')
    USE, INTRINSIC :: ISO_C_BINDING
    IMPLICIT NONE
    INTEGER (C_INT), INTENT(IN), VALUE :: scenario,region,soilorder,topography,ASoildepth
    REAL (C_DOUBLE), INTENT(IN), VALUE :: rainfall,Snumdairy,Snumsheep,Snumbeef,Snumdeer
    REAL (C_DOUBLE), INTENT(IN), VALUE :: AdditionalNitrogen,Supplementrate
    INTEGER (C_INT), INTENT(IN), VALUE :: SupplementType
    REAL (C_DOUBLE), INTENT(OUT) :: Nloss,Ploss
    CHARACTER(C_CHAR), INTENT(OUT) :: ErrStr(*)
  END FUNCTION CluesOvr
END INTERFACE
IBM代码还使用

 pointer (q,CluesOvr)
 p = loadlibrary("CluesOvr.dll")
 q = getprocaddress(p, "CluesOvr")

访问该函数。我对gfortran不这么做。

存在
borlandmm.dll
表明您的任务几乎不可能完成。该DLL用于允许不同模块(例如,可执行文件和DLL)共享一个通用的Delphi内存管理器。这允许一个模块(比如说可执行文件)分配一个Delphi字符串,并将其传递给另一个模块(比如说DLL),后者反过来可以取消分配该字符串

除非两个模块共享同一堆,否则这种体系结构无法工作。
borlandmm.dll
库使得跨模块的堆共享成为可能。任何希望使用其主机的Delphi内存管理器的DLL都包括
Sharemem
单元,该单元依次使用
borlandmm.DLL
库来实现内存管理器共享

现在,您的Fortran主机可能无法满足要求的契约。唯一能提供Delphi内存管理器的是Delphi主机。将要发生的是,您调用的DLL认为它负责释放传递的内存。DLL可能接收堆分配的Delphi
string
变量。当DLL试图释放内存时,该内存已在Fortran主机进程中分配。这种不匹配很可能导致访问违规。这些不一定在每次调用函数时都会发生


使用
borlandmm.DLL
的这个DLL的设计是合理的,前提是它只能从Delphi主机调用。如果DLL的开发人员知道他们在做什么,那么他们就会知道这个限制。您没有DLL的文档这一事实向我表明,您已经从另一个程序中提取了DLL,并试图以一种非设计的方式使用它。您成功的机会非常低。

如果我们不知道接口合同是什么,我们将无能为力。函数的Pascal声明是什么?或者你有一个C或C++头文件吗?你的Fortran代码是什么?如果您需要我们的帮助,您需要提供互操作界面的两面。不要试图在评论中提出这个问题。在问题中提问。进行编辑。不,我没有Delphi代码,只有代码的fortran端和一个DLL(也附带一个boreland DLL,我认为它与Delphi代码有关)。如果你没有接口另一端的规范,你怎么知道如何调用它?我们怎么能帮上忙呢?是时候放弃没有文档的DLL,使用正确文档化的库了。要求我们对完全没有任何规范的东西进行推理是浪费每个人的时间。简单地说,这与编程无关。了解这个DLL是什么以及为什么要使用没有文档的DLL会很有用。DLL应该由哪个应用程序使用?这不是一般用途的消费品,是吗?谢谢你的解释。我也许能在另一个机构找到代码的来源,看看我能从哪里得到它。与科学家打交道,不一定是最好的代码编写者。我必须尽可能地应付。
INTERFACE
 LOGICAL (C_BOOL) FUNCTION CluesOvr(scenario,region,soilorder,topography,rainfall, &
    ASoildepth,Snumdairy,Snumsheep,Snumbeef,Snumdeer,AdditionalNitrogen, &
    Supplementrate, SupplementType,Nloss,Ploss, &
    ErrStr) BIND (C, name='CluesOvr')
    USE, INTRINSIC :: ISO_C_BINDING
    IMPLICIT NONE
    INTEGER (C_INT), INTENT(IN), VALUE :: scenario,region,soilorder,topography,ASoildepth
    REAL (C_DOUBLE), INTENT(IN), VALUE :: rainfall,Snumdairy,Snumsheep,Snumbeef,Snumdeer
    REAL (C_DOUBLE), INTENT(IN), VALUE :: AdditionalNitrogen,Supplementrate
    INTEGER (C_INT), INTENT(IN), VALUE :: SupplementType
    REAL (C_DOUBLE), INTENT(OUT) :: Nloss,Ploss
    CHARACTER(C_CHAR), INTENT(OUT) :: ErrStr(*)
  END FUNCTION CluesOvr
END INTERFACE
 pointer (q,CluesOvr)
 p = loadlibrary("CluesOvr.dll")
 q = getprocaddress(p, "CluesOvr")