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

Calling IVF from C# only via dll?

onkelhotte
New Contributor II
283 Views
Is there another way to call Frotran Routines (IVF9.1) from C# (VS2005) or do I have to compile my Fortran files as a dll?
I tried to implement following Fortran (as an dll):
Code:
real*8 function EXPFUNCTION (basisA, exponentB)
!DEC$ ATTRIBUTES DLLEXPORT::EXPFUNCTION
implicit none

real*8 basisA, exponentB

EXPFUNCTION = basisA**exponentB

end function EXPFUNCTION

In C# I try to use it that way:
Code:
[DllImport("fortrandll.dll")]
private extern static double EXPFUNCTION(double basisA, double exponentB);

private void buttonFunction_Click(object sender, EventArgs e)
{
    double ergebnis,basis,exponent;
    basis = 2.4d;
    exponent = 3.7d;
    ergebnis = EXPFUNCTION(basis, exponent);
}


I copied the dll in the executable path of the C# project. But when I use the EXPFUNCTION I get an exception, that my program had tried to read or write from protected memory (System.AccessViolationException: Es wurde versucht, im geschtzten Speicher zu lesen oder zu schreiben. Dies ist hufig ein Hinweis darauf, dass anderer Speicher beschdigt ist.)
Thanks in advance,
Markus

Message Edited by OnkelHotte on 05-31-200605:20 AM

Message Edited by OnkelHotte on 05-31-200605:21 AM

0 Kudos
2 Replies
onkelhotte
New Contributor II
283 Views

I discovered a solution on my own (okay, a colleague helped a little bit...)

I was not aware of the fact that subroutines and function are called by reference and not by value. So you need to do the following steps in Fortran:

Code:

subroutine FORTRANSUM (summandA, summandB, summeC)
!DEC$ ATTRIBUTES DLLEXPORT::FORTRANSUM
!DEC$ ATTRIBUTES VALUE    ::summandA
!DEC$ ATTRIBUTES VALUE    ::summandB
!DEC$ ATTRIBUTES REFERENCE::summeC

implicit none

integer*4 summandA, summandB, summeC

summeC = summandA + summandB

end subroutine FORTRANSUM


real*8 function EXPFUNCTION (basisA, exponentB)
!DEC$ ATTRIBUTES DLLEXPORT::EXPFUNCTION
!DEC$ ATTRIBUTES VALUE    ::basisA, exponentB
implicit none

real*8 basisA, exponentB

EXPFUNCTION = basisA**exponentB

end function EXPFUNCTION



In C# I had to do this:

Code:

[DllImport("fortrandll.dll")]
private extern static double EXPFUNCTION(double basisA, double exponentB);

private void buttonFunction_Click(object sender, EventArgs e)
{
    double ergebnis,basis,exponent;
    basis = 2.4d;
    exponent = 3.7d;
    ergebnis = EXPFUNCTION(basis, exponent);
}

[DllImport("fortrandll.dll")]
unsafe private extern static void FORTRANSUM(int summandA, int summandB, int *summeC);

unsafe private void buttonSubroutine_Click(object sender, EventArgs e)
{
    int a=5, b=9, ergebnis=0;
    FORTRANSUM(a,b,&ergebnis);
}



It is unsafe code, when you operate with pointers in C#. So you have to declare your Fortran method and the C# method that uses your Fortran methodas unsafe.

Concerning my first question: Do you have to build your Fortran project as a dll? Is that because you have to use two different projects in VS2003+ (one Fortran and one C#)?


Thanks in advance,
Markus

0 Kudos
Steven_L_Intel1
Employee
283 Views
Yes, you have to build the Fortran code as a DLL.

You also need to specify that the Fortran routine uses the STDCALL mechanism, as that is the C# defsult.
0 Kudos
Reply