简体   繁体   English

将数组从fortran传递给C ++函数

[英]Passing an array from fortran to a C++ function

I have a main program in Fortran . 我在Fortran中有一个主程序。 I am using Intel Visual Fortran XE 2011 on Visual Studio 2010. I would like to use a function which is coded in C++ . 我在Visual Studio 2010上使用Intel Visual Fortran XE2011。我想使用在C ++中编码的函数。 The function I'm using is getting several arrays (input - set from the main fortran program) and use them to form an output array (to be returned to the main fortran program). 我正在使用的功能是获取多个数组(输入-从主要的fortran程序中设置),并使用它们形成输出数组(返回至主要的fortran程序)。 I've taken the following steps: 我已采取以下步骤:

1)I created a Fortran project with the Fortran main program and module and I set it as "startup project". 1)我使用Fortran主程序和模块创建了一个Fortran项目,并将其设置为“启动项目”。

2)I created a C++ project of type "static library". 2)我创建了一个类型为“静态库”的C ++项目。

3)I added $(IFORT_COMPILERvv)\\compiler\\lib\\ia32 as explained here http://software.intel.com/en-us/articles/configuring-visual-studio-for-mixed-language-applications 3)我添加了$(IFORT_COMPILERvv)\\compiler\\lib\\ia32 ,如此处http://software.intel.com/zh-cn/articles/configuring-visual-studio-for-mixed-language-applications所述

The C++ static library is build with no problem. C ++静态库的构建没有问题。 The errors I get is about the declaration of the real(8) variables in the fortran program. 我得到的错误与在fortran程序中real(8)变量的声明有关。

I get the following two errors for all real(8) declarations, ie 6 errors in total: 对于所有real(8)声明,我得到以下两个错误,即总共6个错误:

error #5082: Syntax error, found '(' when expecting one of: :: %FILL , TYPE BYTE CHARACTER CLASS DOUBLE DOUBLECOMPLEX DOUBLEPRECISION ... 错误#5082:语法错误,当期望以下情况之一时发现'(':::%FILL,TYPE BYTE CHARACTER CLASS DOUBLE DOUBLECOMPLEX DOUBLEPRECISION ...

error #5082: Syntax error, found '::' when expecting one of: ( * , ; [ / = => 错误#5082:语法错误,当期望以下其中一项时,发现“ ::”:(*,; [/ = =>

Here is the code I used: 这是我使用的代码:

Main Fortran Program: 主要的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

And the C++ function is: 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];
     }
}

Could anybody please help me with this issue? 有人可以帮我解决这个问题吗? And would you please let me know if the idea of sending a whole array from a fortran program to a c++ routine is a safe or problematic (better-to-be-avoided) attempt? 您能否让我知道将整个数组从fortran程序发送到c ++例程的想法是安全的还是有问题的(最好避免)?

Your Fortran syntax is out. 您的Fortran语法已过期。 You have the real kind twice. 你有两次真正的善良。 Try 尝试

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

etc. 等等

C_DOUBLE is a named constant. C_DOUBLE是一个命名常量。 It happens to have the value 8 with that processor. 该处理器恰好具有值8。

Also: 也:

  • you are missing the argument m in the Fortran interface body for the C function. 您在Fortran接口主体中缺少C函数的参数m
  • you change your mind about the name of the subroutine in the Fortran interface body between the opening and closing statement! 您会改变在开头和结尾语句之间的Fortran接口主体中子例程的名称的想法!
  • Your C++ for loop less than equal compares against m , that should probably be mm . 您的C ++ for循环小于等于,则与m进行比较,该值应该为mm

There are no inherent problem sending whole arrays in this manner. 以这种方式发送整个数组没有固有的问题。

I had only managed to pass the value of a varible from C function to fortran function. 我只设法将变量的值从C函数传递给fortran函数。

I have here pasted the two source files namely main.c and fortran.f You can use these two files in microsoft visual studio 10. After doing all the settings in visual studio as suggested in page http://software.intel.com/en-us/articles/configuring-visual-studio-for-mixed-language-applications , you need to make another change as; 我在这里粘贴了两个源文件,即main.c和fortran.f。您可以在Microsoft Visual Studio 10中使用这两个文件。按照http://software.intel.com/页上的建议在Visual Studio中进行所有设置之后。 zh-cn / articles / configuring-visual-studio-for-mixed-language-applications ,您需要进行以下更改:

  1. go to the project property of C/C++ static library ; 转到C / C ++静态库的项目属性;
  2. go to C/C++ 转到C / C ++
  3. go to Code Generation 转到代码生成
  4. set the Runtime Library to Multi-threaded Debug (/MTd) 将运行时库设置为多线程调试(/ MTd)

now you can build the program.... 现在您可以构建程序了。

main.c: main.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: 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 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM