xuguangyue2001 发表于 2005-12-15 15:40:23

VC++调用Fortran生成的dll文件出现的动态数组问题(急)

VC和CVF中编译连接通过都没问题,但是当动行时就会出现:
   “0x000557b6”指令引用的“0x000557b6”内存,该内存不能为“read”,但是当我把Fotran里的动态数组改为静态时就没错误了,可是我的程序必须用动态数组,请各位老师能帮我解答一下!!!
    Fotran代码:
                  subroutinearraytest(n,arr)
                  $ATTRIBUTES DLLEXPORT :: ARRAYTEST
                  implicit none
                  integer::i,j,n
                  real,dimension(:,: ),allocatable:: arr
                                  n=2
                                 allocate(arr(0:n,0:n))
                  do i=0,2
                        do j=0,2
                          arr(i,j)=n+i+j
                         end do
                     end do
                  end subroutinearraytest
   C++代码:
      HINSTANCE hIns;
    hIns = LoadLibraryEx("EXAM.dll",NULL,DONT_RESOLVE_DLL_REFERENCES);
      typedef float (*MYPROC)(int &a, float b);
    MYPROC fun= (MYPROC)GetProcAddress(hIns,"_ARRAYTEST@8");
     float arr;
    int a = 1;
    fun(a,arr);          //调用Fortran函数
       ::FreeLibrary(hIns);

freefrompassion 发表于 2005-12-15 20:37:52

Re:VC++调用Fortran生成的dll文件出现的动态数组问题(急)

根据你说的调的一下,不知道是不是你要的结果!
动态库fortrandll.f90
____________________________
subroutine arraytest(n,arr)
!DEC$ ATTRIBUTES DLLEXPORT::ARRAYTEST
implicit none
integer i,j,n
real arr(n,n)

do i=1,n
   do j=1,n
      arr(i,j)=n+i+j
   enddo
enddo
end subroutine arraytest
_______________________________

c调用程序 ccallfortrandll.cpp
________________________________
#include "stdafx.h"
#include "stdio.h"
#include "Windows.h"

int main(int argc, char* argv[])
{
  typedef void (_stdcall * lpProc)(int *,float []);
  
  HINSTANCE hLibrary=LoadLibrary("fortrandll.dll");
  if(hLibrary==NULL)
       printf("import dll failed");
  lpProc arraytest=(lpProc)GetProcAddress(hLibrary,"_ARRAYTEST@8");
  if(arraytest==NULL)
    printf("function not found\n");

    int a = 3;
  float arr;
    arraytest(&a,arr);
    for(int i=0;i<a;i++)
  {
    for(int j=0;j<a;j++)
    {
      printf("%8.2f\t",arr);
    }
    printf("\n");
  }

  FreeLibrary(hLibrary);
  return 0;
}

运行结果见图,自我感觉在调用过程中对多维数组的操作显得不是很方便,很多情况下,我都是将多维数组分解为多个一维数组进行操作,虽然麻烦些,但可以避免出错,希望对你有用!

xuguangyue2001 发表于 2005-12-15 21:53:12

Re:VC++调用Fortran生成的dll文件出现的动态数组问题(急)

非常感谢freefrompassion兄!!! 很抱歉我说得不太清楚的。
我的Fortran代码里含有:
          real,allocatable:: arr(:,: )
          allocate(arr,n)

就出现我上面说的内存不能read的错误!!
请多多指点非常感谢!!

xuguangyue2001 发表于 2005-12-15 22:13:32

Re:VC++调用Fortran生成的dll文件出现的动态数组问题(急)

因为我要把一个数组声明为全局变量,但是这个数组我又不能事先知道它的维数,所以就用到了动态数组:
real,allocatable:: arr(:,:)
allocate(arr,n)
但是它在C++里一直出错,不知是什么原因

freefrompassion 发表于 2005-12-16 09:52:48

Re:VC++调用Fortran生成的dll文件出现的动态数组问题(急)

嘿嘿,我直接用的是
integer n
real arr(n,n)
这一样的是动态数组啊,只不过是隐式声明而已。
我以前做过一些程序,也是发现利用c和fortran之间交换数据的时候,多维数组不是很好用。我想这个问题主要是语言本身的差别,上面的问题是不是可以用内存分配来解释。
首先在c的主程序中,是利用
int a=3;
float arr[3; 此时以arr为首地址的数组空间已经分配完毕。然后调用动态库里的函数。此函数中又有 allocate(arr(n,n)) 这样的语句,将导致程序再一次对数组arr的分配。可能出于内存保护等方面的考虑,程序报错。如果采用隐式声明,real arr(n,n)这样等于直接告诉程序arr的大小,也保证它和传过来参数的一致。
这个问题我也是断断续续的考虑过一段时间,有机会我们可以讨论讨论!

xuguangyue2001 发表于 2005-12-16 11:11:19

Re:VC++调用Fortran生成的dll文件出现的动态数组问题(急)

谢谢这位兄弟,我还有一点问题,这样调用的话它就不是全局变量了,我想把它用module做成全局变量,但是全局变量声明的时候需要给出维数而维数又是以后计算才得出的,请问有没有什么解决的好方法?而且我的好多子程序还要循环调用.我想了半天就用了allocate(),但是在C++中调用又出错.
    能不能把你的QQ号或Email都留一下,非常感谢!!!

freefrompassion 发表于 2005-12-16 12:00:48

Re:VC++调用Fortran生成的dll文件出现的动态数组问题(急)

如果用module来做的话,也没有什么问题,你的subroutine 中一样可以use。
这样你可以现单独做个subroutine用来分配数组。完了和以前一样用就可以了。如果完善一点的话,还可以专门做几个函数用来做c和fortran 之间的数据传递!

xuguangyue2001 发表于 2005-12-17 21:38:47

Re:VC++调用Fortran生成的dll文件出现的动态数组问题(急)

非常感谢freefrompassion兄,但是用module的话,module没办法调用子程序subroutine来计算数组维数,有没有什么好办法?

freefrompassion 发表于 2005-12-18 13:40:34

Re:VC++调用Fortran生成的dll文件出现的动态数组问题(急)

维数你干脆通过c程序传给fortran,然后分配,应该没问题。

xuguangyue2001 发表于 2005-12-18 20:17:48

Re:VC++调用Fortran生成的dll文件出现的动态数组问题(急)

谢谢!

xuguangyue2001 发表于 2005-12-18 20:57:17

Re:VC++调用Fortran生成的dll文件出现的动态数组问题(急)

我想再问一下C++与fortran数值上传递对类型匹配有什么要求?

xuguangyue2001 发表于 2005-12-18 22:12:27

Re:VC++调用Fortran生成的dll文件出现的动态数组问题(急)

我用C++调用Fortran的dll,出现了好多意想不到的问题::如
    lambda=(DN*H*Omega*Omega/D)
    lambda=(DN*H*Omega*Omega/D)**0.25
错误居然出现在第二句,错误提示是:0x0000005:Access Violation
我解决不了呀,挺郁闷的!不知是什么问题!

freepu 发表于 2005-12-19 03:33:42

Re:VC++调用Fortran生成的dll文件出现的动态数组问题(急)

不同语言之间的多维数组传递最好采用一维数组解决:
如x数组可用如下一维数组xx表示。
该数组对应原数组中元素x如下: xx。
一维数组的传递是十分简单的。

lambda=(DN*H*Omega*Omega/D)**0.25
中(DN*H*Omega*Omega/D)是不是负数?

xuguangyue2001 发表于 2005-12-19 09:11:58

Re:VC++调用Fortran生成的dll文件出现的动态数组问题(急)

(DN*H*Omega*Omega/D)不是负数,我用了单步执行可以看出数值的变化它的值为0.15,所以我感到这个错误莫明其妙的:(

xuguangyue2001 发表于 2005-12-19 09:13:12

Re:VC++调用Fortran生成的dll文件出现的动态数组问题(急)

可能我的算法太复杂了
页: [1]
查看完整版本: VC++调用Fortran生成的dll文件出现的动态数组问题(急)