1

我在Fortran中有一个主程序。我在 Visual Studio 2010 上使用 Intel Visual Fortran XE 2011。我想使用一个用C++编码的函数。我正在使用的函数是获取几个数组(输入 - 从主 fortran 程序设置)并使用它们形成一个输出数组(返回到主 fortran 程序)。我已采取以下步骤:

1)我用Fortran主程序和模块创建了一个Fortran项目,并将其设置为“启动项目”。

2)我创建了一个“静态库”类型的 C++ 项目。

3)我$(IFORT_COMPILERvv)\compiler\lib\ia32按照此处的说明添加了http://software.intel.com/en-us/articles/configuring-visual-studio-for-mixed-language-applications

C++ 静态库的构建没有问题。我得到的错误是关于real(8)fortran 程序中变量的声明。

对于所有 real(8) 声明,我得到以下两个错误,即总共 6 个错误:

错误 #5082: 语法错误,当期望以下之一时发现 '(': :: %FILL , TYPE BYTE CHARACTER CLASS DOUBLE DOUBLECOMPLEX DOUBLEPRECISION ...

错误 #5082:语法错误,当期望以下之一时发现 '::': ( * , ; [ / = =>

这是我使用的代码:

主 Fortran 程序:

Program Fort_call_C

use iso_c_binding

implicit none

interface 

   subroutine vec_sum_c(a,b,c) bind (C, name = "vec_sum_c")

      use iso_c_binding

      implicit none

      real(8) (c_double), intent (in), dimension (*) :: a,b
      real(8) (c_double), intent (out), dimension (*) :: c

   end subroutine get_filled_ar

end interface  

integer:: i
integer (c_int)::m
real(8)(c_double),dimension(:):: a, b, c

open(unit=10, file="input_arrays.txt",status="unknown")
read(10,*) m
allocate(a(m),b(m),c(m))

do i=1,m
   read(10,*)a(i),b(i)
end do
close(10)

call vec_sum_c(m,a,b,c)

do i=1,m
   print*, c(i)
end do

pause

end program

而 C++ 函数是:

extern"C" void vec_sum_c(int *m, double *a, double *b, double *c){
    int mm = *m;
    for(int i=0;i<=m-1;i++){
        c[i]=a[i]+b[i];
     }
}

有人可以帮我解决这个问题吗?请告诉我将整个数组从 fortran 程序发送到 c++ 例程的想法是安全的还是有问题的(最好避免)尝试?

4

2 回答 2

2

您的 Fortran 语法已失效。你有两次真正的那种。尝试

REAL(C_DOUBLE), INTENT(IN), DIMENSION(*) :: a, b

等等

C_DOUBLE 是一个命名常量。该处理器的值恰好为 8。

还:

  • 您在 C 函数的 Fortran 接口主体中缺少参数m
  • 您改变了对 Fortran 接口主体中开始和结束语句之间子例程名称的看法!
  • 您的 C++ for 循环小于等于比较m,应该是mm.

以这种方式发送整个数组没有固有的问题。

于 2013-05-02T05:43:45.317 回答
0

我只设法将变量的值从 C 函数传递到 fortran 函数。

我在这里粘贴了两个源文件,即 main.c 和 fortran.f 您可以在 Microsoft Visual Studio 10 中使用这两个文件。按照页面http://software.intel.com/中的建议在 Visual Studio 中进行所有设置后en-us/articles/configuring-visual-studio-for-mixed-language-applications,您需要进行另一项更改;

  1. 转到 C/C++ 静态库的项目属性;
  2. 转到 C/C++
  3. 转到代码生成
  4. 将运行时库设置为多线程调试 (/MTd)

现在您可以构建程序....

主.c:

#include <stdio.h>
#include <malloc.h>

void testc(double **pa, double **p)
{
 double b;
 double *a, *c;
 int m;

 c = (double*) malloc(sizeof(double));
 *c = 10;

 *p = c;

 a = (double*) malloc(sizeof(double)*5);
 a[0]=1.23;
  a[1]=2.46;
a[2]=3.69;
 a[3]=4.11;
 a[4]=7.21;
 *pa=a;
 for (m=0;m<5;m++)
 {
    b=a[m];
    b=b+1.0;
    a[m]=b;
  }
 } 

fortran.f:

 program test
  use iso_c_binding
  implicit none
 interface
  subroutine testc(pa, m) bind(c)
  use iso_c_binding
   type(c_ptr):: m
   type(c_ptr):: pa
  end subroutine testc
  end interface

  type(c_ptr) :: pa
  type(c_ptr) :: m
  real(c_double),pointer::fpa(:)
   real(c_double),pointer::fm(:)

    call testc(pa,m)
     call c_f_pointer(pa, fpa, [5])
     call c_f_pointer(m, fm, [1])
     print *, fm(1)
    print*, fpa(1)
   pause

 end program test 
于 2013-07-26T21:01:58.830 回答