Silverfrost Forums

Welcome to our forums

Passing Integers and Character String from C# to FORTRAN

16 Feb 2013 6:59 #11570

Dear Forums,

I am developing an application in Visual Studio C# and passing arguments from C# into FORTRAN.

I am having problems passing integers and character strings. C# is not my strongest programming language. Here's is the syntax I am trying to implement:

int i = 50;

    int* ircnt = &i;
    char cright;
    char title1;
    char title2;
    char version;
    char year;

    ASME97RefProps.SPINIT(i, cright, title1, title2, version, year);

Visual studio is throwing an error, 'No overload for method 'SPINIT' takes '6' arguments'

Here's the FORTRAN code I am trying to call from C#

C************************************************************* SUBROUTINE SPINIT(irrc,cr,title1,title2,version,year) implicit DOUBLE PRECISION(a-h,o-z) C************************************************************* C include 'nstmcon.inc' include 'nuconv.inc' include 'ntol.inc' include 'nlevel.inc' C character60 cr character40 title1,title2 character10 version character4 year

18 Feb 2013 6:21 #11575

In your fortran code, add this line after the function statement:

ASSEMBLY_INTERFACE(NAME='SPINIT')

Also, make sure that the fortran dll is included in your C# references.

Jill

19 Feb 2013 2:34 #11582

Jill, Thank you for your response. But, my problem is not seeing the function inside of C#. I can see all the fortran functions inside c#. My problem is that I don't know how to pass character string from C#.net into fortran.

19 Feb 2013 1:35 #11584

We are calling a fortran dll from a C# program, and pass in a object we've defined and a boolean. However, we do call a lot of C# methods in the fortran. The fortran was converted from F77, so we are using the fixed file format.

For example, we have a fortran method in this pattern:

      REAL FUNCTION MYFACTOR(PLANTCODE, MATERIAL, ACCOUNTNUMBER, QUOTEDATE)
      IMPLICIT NONE
C - Passed Variables
      CHARACTER PLANTCODE*(*), MATERIAL*(*), ACCOUNTNUMBER*(*), QUOTEDATE*(*)      
C - Local Variables
      CHARACTER FACTORYEAR*2, FACTORMONTH*2
      REAL RETURNVALUE, ADJUSTFACTOR
      STRING SFACTORYEAR, SFACTORMONTH
      ASSEMBLY_EXTERNAL(name='namespace.CSharpFactor') GetFactor
C -
      RETURNFACTOR = 0
      GetFactor(PLANTCODE, MATERIAL, ACCOUNTNUMBER, RETURNFACTOR,
     *  SFACTORYEAR, SFACTORMONTH)
      FACTORYEAR = SFACTORYEAR
      FACTORMONTH = SFACTORMONTH
C-   Adjust return factor
      CALL ADJUST_FACTOR(FACTORMONTH, FACTORYEAR, PLANTCODE, 
     *  SALESACCT, ADJUSTFACTOR)
      RETURNFACTOR = RETURNFACTOR * ADJUSTFACTOR

      MYFACTOR = RETURNFACTOR
      RETURN
      END

The C# method prototype is

public static short CSharpFactor(string plantCode, string material, string accountnumber, ref float returnFactor, ref string factorYear, ref string factorMonth)

Maybe passing STRINGs and converting them to CHARACTERs will work.

Jill

19 Feb 2013 2:22 #11585

Hi Jill,

How are the plantCode, and material arguments to the CSharpFactor function dimensioned within your C# code?

R/ Bill

19 Feb 2013 2:38 #11586

They are just strings. Here's a the basic code.

using System;
using System.Text;

namespace MyNamespace
{
  public static class MyClass
  {
    public static short CSharpFactor(string plantCode, string material, string accountnumber, ref float returnFactor, ref string factorYear, ref string factorMonth)
    {
      returnFactor = 0.0F;
      factorYear = String.Empty;
      factorMonth = String.Empty;

      plantCode = plantCode.Trim();
      accountnumber = accountnumber.Trim();

      // Look up the factor information from the database
      // Set the return variables to the values returned

      // Exit the method
      return (0);
    }
  }
}

We don't use character arrays in the C# code. We use String/string. The String class has a few more options, but they are basically the same class. The .NET compiler will automatically convert between the two types.

The original fortran code the defines the plant code and account numbers are

CHARACTER PLANTCODE*4, ACCOUNTNUMBER*6

Jill

19 Feb 2013 4:59 #11587

Hi Jill,

I see that you changed the original FORTRAN code for the dimension of the character strings from 'PLANTCODE4' to 'PLANTCODE(*)'. I haven't seen this type dimensioning of character strings, can you please offer an explanation. Is this like a more generic way of dimensioning character strings in FORTRAN when the length of the character string is unknown?

Thank you, Bill

19 Feb 2013 6:24 #11588

I think it was a 77 construct. I did a quick search and found this link http://h21007.www2.hp.com/portal/download/files/unprot/Fortran/docs/lrm/lrm0085.htm

It says:

(http://h21007.www2.hp.com/portal/download/files/unprot/Fortran/docs/lrm/lrm0085.htm)

It says: [quote:5f05acf624]An automatic object can appear in a character declaration. The object cannot be a dummy argument, and its length must be declared with a specification expression that is not a constant expression.

The length specified for a character-valued statement function or statement function dummy argument of type character must be an integer constant expression.

When an asterisk length specification () is used for a function name or dummy argument, it assumes the length of the corresponding function reference or actual argument. Similarly, when an asterisk length specification is used for a named constant, the name assumes the length of the actual constant it represents.

The form CHARACTER*(*) is an obsolescent feature in Fortran 95.

The plant code and account numbers are defined as CHARACTER* in the main program, but we define them as CHARACTER*(*) in all subroutines and functions.

I would not worry about that. I would try using strings instead of character arrays in the C# code and passing those strings to the fortran module, and converting them to characters arrays there.

Currently your C# code is only passing single characters to the SPINIT routine. That could be your problem.

Jill

19 Feb 2013 11:13 #11589

Hi Jill.

Thank you for your help. I've convert over to strings. But, now the silverfrost compile is saying that 'Argument '2': cannot convert 'string' to 'Salford.Fortran.Character*' What is a Salford.Fortran.Character? I thought that the compiler would natural cast the C# string into the FORTRAN character.

Bill

20 Feb 2013 1:26 #11593

I would change your fortran to this:

C************************************************************* 
SUBROUTINE SPINIT(irrc,scr,stitle1,stitle2,sversion,syear) 
implicit DOUBLE PRECISION(a-h,o-z) 
C************************************************************* 
C 
include 'nstmcon.inc' 
include 'nuconv.inc' 
include 'ntol.inc' 
include 'nlevel.inc' 
C
string scr,stitle1,stitle2,sversion,syear
C 
character*60 cr 
character*40 title1,title2 
character*10 version 
character*4 year
C
cr = scr
title1 = stitle1
title2 = stitle2
version = sversion
year = syear

Now I have not tested this. But it is very similar to what we do with the object we pass in to our starting function. We just set the fortran character arrays to the string field in the object.

Jill

Please login to reply.