forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Passing .NET array from FORTRAN to C#

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
RS



Joined: 22 Jun 2008
Posts: 22

PostPosted: Mon Jun 30, 2008 8:24 pm    Post subject: Passing .NET array from FORTRAN to C# Reply with quote

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
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7924
Location: Salford, UK

PostPosted: Tue Jul 01, 2008 12:23 pm    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
RS



Joined: 22 Jun 2008
Posts: 22

PostPosted: Tue Jul 01, 2008 5:03 pm    Post subject: .NET Arrays passed back to .NET code Reply with quote

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
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7924
Location: Salford, UK

PostPosted: Wed Jul 02, 2008 7:07 am    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
Andrew



Joined: 09 Sep 2004
Posts: 232
Location: Frankfurt, Germany

PostPosted: Thu Jul 03, 2008 8:47 pm    Post subject: Reply with quote

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
View user's profile Send private message
RS



Joined: 22 Jun 2008
Posts: 22

PostPosted: Wed Jul 16, 2008 9:08 pm    Post subject: Thanks. Reply with quote

I will experiment with it. If you don't mind, I will follow up if I have some additional questions.
Back to top
View user's profile Send private message
RS



Joined: 22 Jun 2008
Posts: 22

PostPosted: Fri Jul 18, 2008 12:14 pm    Post subject: OBJECT("ClassLibrary3.Class1") :: OBJ Reply with quote

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
View user's profile Send private message
j clark



Joined: 29 Mar 2008
Posts: 20
Location: Bala Cynwyd (Pennsylvania)

PostPosted: Sat Jul 19, 2008 3:03 pm    Post subject: Arrays 101 Reply with quote

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
View user's profile Send private message AIM Address
RS



Joined: 22 Jun 2008
Posts: 22

PostPosted: Sat Jul 19, 2008 9:56 pm    Post subject: What is the C# code that goes with this? Reply with quote

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
View user's profile Send private message
RS



Joined: 22 Jun 2008
Posts: 22

PostPosted: Sun Jul 20, 2008 12:38 am    Post subject: This seems to work Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group