- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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.
Link Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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);
.....................
}
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);
.....................
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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) )
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page