View previous topic :: View next topic |
Author |
Message |
RS
Joined: 22 Jun 2008 Posts: 22
|
Posted: Mon Jun 30, 2008 8:24 pm Post subject: Passing .NET array from FORTRAN to C# |
|
|
I am trying, so far without success, to pass an entire array from FORTRAN to C#.NEt. I understand that a .NET array must be created and instantiated in FORTRAN and that I must assign values to each of its values from a FORTRAN array by adjusting for i = 0 versus i = 1 initial index. The question is how to pass this array to C#. I tried
ASSEMBLY_EXTERNAL("System.Array.Copy") :: ArrayCopy
My idea was to copy the C# array created in the FORTRAN subroutine to a specific C# array passed as an argument to the fortran subroutine. Is this the best way of doing this?
Secondly, it looks as if using the instance method Array.SetValue I can assign to each element of an array but it would be better if I could use the static method Array.Copy or else another, more intelligent way of doing the same thing. I would appreciate any guidance. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Tue Jul 01, 2008 12:23 pm Post subject: |
|
|
It is not clear to me what you are aiming to do.
Have you read the FTN95 help topic under .NET platform->.NET programming->.NET arrays? |
|
Back to top |
|
|
RS
Joined: 22 Jun 2008 Posts: 22
|
Posted: Tue Jul 01, 2008 5:03 pm Post subject: .NET Arrays passed back to .NET code |
|
|
Yes, I did read it, but how to do what I am asking was not clear to me from the documentation. Basically, I need to get a Fortran array calculated in the Fortran subroutine and pass that to the .NET code that called the Fortran subroutine.
The documentation or perhaps one of the examples does talk clearly about the reverse operation, which is how to pass an array to a Fortran subroutine and how to convert that to a Fortran array. If there is something as clear on the reverse operation, please point me to it.
Thanks. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Wed Jul 02, 2008 7:07 am Post subject: |
|
|
If you are passing a Fortran array as an argument then you may get some ideas by looking at the ildasm of the compiled code. This will show you the number and type of the actual arguments that are being passed.
The array will appear as a pointer to a contiguous block of column-ordered data. In the C# code you may be able to use "unsafe" pointers to extract the data into a more usable form.
However, there is probably a simpler way to do the transfer. |
|
Back to top |
|
|
Andrew
Joined: 09 Sep 2004 Posts: 232 Location: Frankfurt, Germany
|
Posted: Thu Jul 03, 2008 8:47 pm Post subject: |
|
|
An example of passing .NET arrays from Fortran can be found here:
http://forums.silverfrost.com/viewtopic.php?t=1077
This is a specific example to demonstrate what to do with a byte array, but its easy to adapt to what you need.
The code example from the above link is below:
Fortran
Code: |
INTEGER F_ARRAY(256)
OBJECT("ClassLibrary3.Class1") :: OBJ
ASSEMBLY_EXTERNAL(name="ClassLibrary3.Class1.TestRoutine") :: TESTROUTINE
OBJECT("System.Int32[]") C_ARRAY
OBJ = new@("ClassLibrary3.Class1")
C_ARRAY=NEW@("System.Int32[]",256)
! make sure the indexing is correct
DO I=0,255
F_ARRAY(I + 1) = I
C_ARRAY(I) = F_ARRAY(I + 1)
END DO
CALL TESTROUTINE(OBJ, C_ARRAY)
END PROGRAM
|
C#
Code: |
public void TestRoutine(int[] arr)
{
byte[] ba = new byte[arr.Length];
for (int i = 0; i < arr.Length; i++)
{
ba[i] = Convert.ToByte(arr[i]);
}
}
|
If you need to actually return a .NET array then you can declare a function that returns this, or you could pass a .NET array in as an INTENT(INOUT) and declare it appropriately in the C#.
Passing arrays like this around, so long as they are .NET arrays should be no issue. As you say, you just need to make sure the indexing is OK and as you can see in the example, you can create and assign as shown. |
|
Back to top |
|
|
RS
Joined: 22 Jun 2008 Posts: 22
|
Posted: Wed Jul 16, 2008 9:08 pm Post subject: Thanks. |
|
|
I will experiment with it. If you don't mind, I will follow up if I have some additional questions. |
|
Back to top |
|
|
RS
Joined: 22 Jun 2008 Posts: 22
|
Posted: Fri Jul 18, 2008 12:14 pm Post subject: OBJECT("ClassLibrary3.Class1") :: OBJ |
|
|
What does this line do?
OBJECT("ClassLibrary3.Class1") :: OBJ
I have the Fortran code as a reference in the C# Windows Form Application, so I don't have a class library.
With respect to passing the array as INTENT(INOUT), is there sample code somewhere in the forum or can youo provide an example?
Thanks. |
|
Back to top |
|
|
j clark
Joined: 29 Mar 2008 Posts: 20 Location: Bala Cynwyd (Pennsylvania)
|
Posted: Sat Jul 19, 2008 3:03 pm Post subject: Arrays 101 |
|
|
It's not all that difficult once you get used to it. To copy an array from c# to a Fortran subroutine and back again, assuming the routine has the array as it's only parameter:
SUBROUTINE MESS_WITH_IT(c_array)
1. Declare the c# array in FTN instantate it:
OBJECT ("System.Int32[]") c_array
c_array=NEW@("System.Int32[]",MAXSIZE)
2. Copy it to a FTN array:
DO I=1,MAXSIZE
F_ARRAY(I)=c_array(I-1)
END DO
3. Do what you have to do with the array, then copy it back to the c# array and return:
DO I=1,MAXSIZE
c_array(I-1)=F_ARRAY(I)
END DO
RETURN
I think this will work with any numeric array EXCEPT for a BYTE array. Unsigned bytes must be first converted to at least Int16 to pass. In FTN, the array can be copied to a byte array, if needed. |
|
Back to top |
|
|
RS
Joined: 22 Jun 2008 Posts: 22
|
Posted: Sat Jul 19, 2008 9:56 pm Post subject: What is the C# code that goes with this? |
|
|
My call to the the fortran dll has several arguments, including several arrays. It is not clear to me how C# gets the array from Fortran. Doing just the return that you suggested did not appear to do the job. |
|
Back to top |
|
|
RS
Joined: 22 Jun 2008 Posts: 22
|
Posted: Sun Jul 20, 2008 12:38 am Post subject: This seems to work |
|
|
I pass the the C# array as reference, then declare it within the Fortran subroutine as INTENT(INOUT), then change it. This is probably what Andrew had suggested originally.
Thank you all for the help. |
|
Back to top |
|
|
|