Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29361 Discussions

Fortran calling VB/C# routine, passing an array

commbank
Beginner
607 Views
Hi All,

This is about Fortran calling VB / C# and where at least one argument is a native type array.
Please ignore the fact that it is combining with C# - just think of VB - the answer I seek may work on C# if you can give me a VB answer.

Basically I know and have used VB/C# main program calling a Fortran subroutine. In particular, if the Fortran code is:
sub FortranFoo(aVector)
real*4 vector(10)

then VB / C# would call something like:
FortranFoo( float bVector(0) )

The important bit is VB/C# need to explicity denote the ZERO-th (first) element to pass the whole array in successfully.

BUT, my question is how do you go the other way of Fortran calling a VB/C# subroutine and trying to get an array through?

Specifically my code is below:

C#
public static void plot2D_F90( float[] xvec, float[] yvec) {...... }

Fortran
x=(/1,2,3,4/)
y=(/2,4,6,8/)
call CallbackPlot2D(x,y)

Currently, the program runs, but it will only pass the first element of the array from Fortran. Debugging from the C# end, the array I get for xvec and yvec respectively is 1.0, 2.0.

Does anyone know about this or has done this before.?

Thanks in advance.
0 Kudos
3 Replies
commbank
Beginner
607 Views
After almost one work-day's efforts I think I may have found the answer. Hope this may help others.

The key is this -> VB and C# arrays are different to C/C++.
C/C++ arrays have been travelling back and forth to/from FORTRAN (ie passing as arguments) and this is very well known.

Also well known is VB calling Fortran by passing an array by using the first element only.
eg call fromVBtoFortranSub( a_VB_Array(0) )

What is not well known is calling C# function from Fortran and passing an array.

The solution is almost a trick. Instead of having a C# function like:
csFoo( float[] a)
we make the array into a C/C++ type (i.e. UNMANAGED variable) array.
csFoo( float* a).

Now we are using non .Net arrays, rather more like C/C++ arrays, and we need to use the C# keyword UNSAFE, to make it handle Unmanaged Code (C#/.Net terminology). Please note, to compile this, you need to switch on the C# UNSAFE switch.

The more extended example is below. For the fortran part, the array are just normal fortran arrays, hence not listed here.

By the way, my initial comment about knowing VB solution may lead to a C# solution, may not hold here in the opposite. The solution here may be applicable to VB.Net, but may not be applicable to Classic VB.



----- C# --------------
unsafe public static void plot2D_F90( float* xvec, float* yvec)
{
// Initialize graph
Graph grph = new Graph();
float[] xvecS = new float[4];
float[] yvecS = new float[4];
xvecS[0] = *xvec;
xvecS[1] = *(xvec+1);
xvecS[2] = *(xvec+2);
xvecS[3] = *(xvec + 3);

yvecS[0] = *yvec;
yvecS[1] = *(yvec + 1);
yvecS[2] = *(yvec + 2);
yvecS[3] = *(yvec + 3);

.....................
}

0 Kudos
ArturGuzik
Valued Contributor I
607 Views
Quoting - commbank
Also well known is VB calling Fortran by passing an array by using the first element only.
eg call fromVBtoFortranSub( a_VB_Array(0) )

Hi,

as I'm not sure about second portion of your solution (always thought that calling .Net assembly from Fortran requires Module Wizard produced interfaces and enabling COM interop on .Net side) so I'd comment on the first portion, namely, passing arrays from VB.Net to Fortran. Please read this Intel KB. In short, it reads that Foo(A(0)) type of call works only on 32-bit system by accident, and is never gonna work on 64-bit platform.

A.
0 Kudos
jjfait
Beginner
607 Views
Quoting - ArturGuzik

Hi,

as I'm not sure about second portion of your solution (always thought that calling .Net assembly from Fortran requires Module Wizard produced interfaces and enabling COM interop on .Net side) so I'd comment on the first portion, namely, passing arrays from VB.Net to Fortran. Please read this Intel KB. In short, it reads that Foo(A(0)) type of call works only on 32-bit system by accident, and is never gonna work on 64-bit platform.

A.

Does anyone know if this is the correct way to pass an array from fortran to c#. Also is there a better post for the options used when passing fortran variables to c#. thanks
Jeremy
0 Kudos
Reply