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

Intel Fortran - C# Interoperability

akrallis
Beginner
1,698 Views
Hello ,

We are working on an interoperability project between FORTRAN and C# . The goal is to create a subroutine in DLL form using FORTRAN and then create a managed prototype for this in C# .

The FORTRAN subroutine is a simple program that adds two numbers:

! test_dll.f90
!
! FUNCTIONS/SUBROUTINES exported from test_dll.dll:
! test_dll - subroutine
!
subroutine test_dll(a,b,c)

! Expose subroutine test_dll to users of this DLL
!
!DEC$ ATTRIBUTES DLLEXPORT::test_dll

! Variables
double precision, intent(in) :: a, b
double precision, intent(out) :: c

! Body of test_dll

c = a + b

end subroutine test_dll

And the C# Console Application for this is :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
[DllImport("TEST_DLL.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool TEST_DLL([In] ref double x,
[In] ref double y,
[In, Out] ref double z);
static void Main(string[] args)
{
double x, y, z;
x = 1.5;
y = 0.5;
z = 0;
TEST_DLL(ref x, ref y, ref z);

Console.WriteLine("{0} + {1} = {2}", x, y, z);

Console.ReadKey();

}
}
}
The above example works without any problems .

But whenwe try to make a call to a function of the IMSL library within the FORTRAN dll then we get a:

System.AccessViolationException error from the C# Console application

The Fortran DLL is:

FORTRAN :
! Dll2.f90
!
! FUNCTIONS/SUBROUTINES exported from Dll2.dll:
! Dll2 - subroutine
!
subroutine Dll2 (ido,t1,t2,a,b,c,y)

! Expose subroutine Dll2 to users of this DLL
!
!DEC$ ATTRIBUTES DLLEXPORT::Dll2

INCLUDE 'link_fnl_static.h'
!DEC$ OBJCOMMENT lib:"libguide.lib"

USE IVPAG_INT
USE MYMOD
IMPLICIT NONE

! Variables

TYPE(param_type) :: parameters
integer(4), intent(inout) :: ido
double precision, intent(inout) :: t1, t2, a, b
double precision, intent(inout) :: c
double precision, dimension (0:1), intent (inout) :: y
integer(4) :: neq
double precision :: tol, da, db, dc
double precision, dimension(50) :: PARAM
double precision, dimension(1,1) :: A1

external FCN, FCNJ

!COMMON/MAIN_FCN/da,db,dc

! Body of Dll2

parameters%k = a
parameters%l = b
neq = 1
tol = 1.d-6
PARAM = 0.d0
PARAM(1)=1.D-10
PARAM(4)=5.D8
PARAM(10)=2
PARAM(12)=2
PARAM(13)=2

c = parameters%k+parameters%l

da = a
db = b
dc = c

call d_ivpag(ido, fcn, fcnj, t1, t2, y, tol=tol, param=param)

end subroutine Dll2

!###############################################################

SUBROUTINE FCN(NEQ,X,Y,YPRIME)

IMPLICIT NONE

INTEGER(4) :: NEQ
DOUBLE PRECISION :: da,db,dc,x
DOUBLE PRECISION, DIMENSION(0:1) :: Y, YPRIME

!COMMON/MAIN_FCN/da,db,dc

YPRIME(0) = y(0)**2.d0-(3.d0/2.d0)*y(0)

END SUBROUTINE FCN

!#############################################################

SUBROUTINE FCNJ(NEQ,X,Y,DYPDY)

IMPLICIT NONE

INTEGER(4) :: NEQ
DOUBLE PRECISION :: X
DOUBLE PRECISION, DIMENSION(0:1) :: Y
DOUBLE PRECISION, DIMENSION(0:1,0:1) :: DYPDY

END SUBROUTINE FCNJ
!############################################################

From the debuger we can see that the call d_ivpag works ok but the error occurs in the FCN callback function.

Could this problem be related to the calling convention ? The above example uses the default calling convention.Please note that this example was working in the CVF Fortran.

Any ideas or other help would be highly appriciated .

Thanks in advance .

0 Kudos
1 Solution
Steven_L_Intel1
Employee
1,698 Views
First, please double-check something. You say that "the above example uses the default calling convention". Make sure that the calling convention is not set to CVF in the project properties (External Procedures). If it is, your use of a callback procedure will cause stack corruption. All IMSL callback procedures must be using the default (C) calling convention.

If you are using the default convention, then I suggest trying replacing:

INCLUDE 'link_fnl_static.h'
!DEC$ OBJCOMMENT lib:"libguide.lib"

with:

INCLUDE 'link_fnl_shared.h'

and see if this changes the behavior.

View solution in original post

0 Kudos
16 Replies
Steven_L_Intel1
Employee
1,699 Views
First, please double-check something. You say that "the above example uses the default calling convention". Make sure that the calling convention is not set to CVF in the project properties (External Procedures). If it is, your use of a callback procedure will cause stack corruption. All IMSL callback procedures must be using the default (C) calling convention.

If you are using the default convention, then I suggest trying replacing:

INCLUDE 'link_fnl_static.h'
!DEC$ OBJCOMMENT lib:"libguide.lib"

with:

INCLUDE 'link_fnl_shared.h'

and see if this changes the behavior.
0 Kudos
akrallis
Beginner
1,698 Views
First, please double-check something. You say that "the above example uses the default calling convention". Make sure that the calling convention is not set to CVF in the project properties (External Procedures). If it is, your use of a callback procedure will cause stack corruption. All IMSL callback procedures must be using the default (C) calling convention.

If you are using the default convention, then I suggest trying replacing:

INCLUDE 'link_fnl_static.h'
!DEC$ OBJCOMMENT lib:"libguide.lib"

with:

INCLUDE 'link_fnl_shared.h'

and see if this changes the behavior.
Hello Steve,

The workaround that you proposed has solved the AccessViolationException problem.

The above solution works without problems in a PC where Visual Studio 2008 and Intel FORTRAN with IMSL library are both installed .
When we try to use this dll library in a computer where the IMSL is not installed although we have we put the IMSL_DLL.DLL file in the same folder with the dll library we get an Unable to load DLL 'dll2.dll': The specified module could not be found error.
When we use the dependency walker tool we see that the following dependencies are missing:

LIBIFCOREMD.DLL
LIBMMD.DLL
LIBIFPORTMD.DLL
LIBGUIDE40.DLL

A solution to this problem could be to copy all the above dll files to the same directory whith the initial library . Is there a more efficient way to deploy a dll that makes calls to the IMSL library ?

Thanks in advance .


0 Kudos
Steven_L_Intel1
Employee
1,698 Views
I'm still somewhat skeptical that you have the calling conventions right. I suggested the DLL libraries because I've seen some problems in the past calling statically-linked DLLs from C# or VB.NET. I don't know why this is an issue.

Please do this. Right click on your Fortran DLL project, select Properties, Fortran, Command Line. Copy all of the command options shown and paste them into a reply here. I want to see what you're using.
0 Kudos
akrallis
Beginner
1,698 Views
I'm still somewhat skeptical that you have the calling conventions right. I suggested the DLL libraries because I've seen some problems in the past calling statically-linked DLLs from C# or VB.NET. I don't know why this is an issue.

Please do this. Right click on your Fortran DLL project, select Properties, Fortran, Command Line. Copy all of the command options shown and paste them into a reply here. I want to see what you're using.

These are the command options:

/nologo /names:uppercase /module:"Release" /object:"Release" /c

I'm looking forward for your reply.
0 Kudos
Steven_L_Intel1
Employee
1,698 Views
Those are ALL the options shown?

To answer your earlier question, yes, you would need to copy the IMSL DLLs to the target system, ideally in a folder listed in the PATH environment variable. Your license allows you to do this as long as the purpose is not to provide IMSL functionality directly to users without a license. (If you use IMSL calls as part of your own application functions, that's fine.)
0 Kudos
akrallis
Beginner
1,698 Views
Those are ALL the options shown?

To answer your earlier question, yes, you would need to copy the IMSL DLLs to the target system, ideally in a folder listed in the PATH environment variable. Your license allows you to do this as long as the purpose is not to provide IMSL functionality directly to users without a license. (If you use IMSL calls as part of your own application functions, that's fine.)

Helo Steve ,

Yes all the options of the FORTRAN DLL project are "/nologo /names:uppercase /module:"Release" /object:"Release" /c" .

The problem remains even when we add the following dlls in the same folder as the executable (or the windows/system32 folder):

LIBIFCOREMD.DLL
LIBMMD.DLL
LIBIFPORTMD.DLL
LIBGUIDE40.DLL


The console application in C# still fails with the error " Unable to load DLL 'dll2.dll': Invalid access to memory location" .

From the dependency walker tool we see that the DWMAPI.DLL file can not be found .

Do you have any ideas or workarounds toinvestigate or solvethis issue ? My opinion is that it would simpler if we could use the static library of IMSL in order to build the dll but this path fails to call the callback function fcn of the d_ivpag function (call d_ivpag(ido, fcn, fcnj, t1, t2, y, tol=tol, param=param) ) .

Thanks in advance ,

George .




0 Kudos
cneufeld
Beginner
1,698 Views
Hi George,

I posted a while ago about calling a Fortran function/subroutine from C#. There is an example project here:
http://software.intel.com/en-us/forums/showthread.php?t=52377

It is a simple fortran dll with 3 subroutines that are called from a C# program. You will likely have to rebuild the project. I used to test passing array and variables back and forth, as well as to test debugging inside the fortran code.

When I test the dll with dependancy walker, I get the same DWMAPI.DLL not found error. It is marked as a delay-load dll and I haven't had any problems using the dll on other machines.

You do need to install the Microsoft_VC80_CRT_x86.msm runtime library on a target machine. I found that the Intel DLL's where not enough.

I can't offer any assistance with the IMSL libraries though. Best of luck.

Cheers, Chad
0 Kudos
Steven_L_Intel1
Employee
1,698 Views
George,

Would you please post your new C# console app that calls the DLL calling IMSL? I want to try this myself but I don't know how you're calling the DLL.
0 Kudos
akrallis
Beginner
1,698 Views
George,

Would you please post your new C# console app that calls the DLL calling IMSL? I want to try this myself but I don't know how you're calling the DLL.

Hi Steve ,

The ConsoleApplication1.rar contains the C# project ( Visual Studio 2008) . Please let me know in case you need any additional information.

Thanks in advance ,

George
0 Kudos
Steven_L_Intel1
Employee
1,698 Views
Well, I tried this and the program ran perfectly using the static libraries. Please attach an archive of your Fortran solution. ("Clean" it first to remove dlls and objects.)
0 Kudos
akrallis
Beginner
1,698 Views
Well, I tried this and the program ran perfectly using the static libraries. Please attach an archive of your Fortran solution. ("Clean" it first to remove dlls and objects.)

Hello Steve,

I have attached the Fortran dll project. Please note that when the C# project runs on a PC whereFortean withimsl productare installed, everything runs without a problem. On the other hand when we use the C# project on a computer with the Visual Studio 2008 (without Fortran and IMSL installed), we get the 'Unable to load DLL error'.

Thank you in advance
0 Kudos
Steven_L_Intel1
Employee
1,698 Views
I would expect that if you linked to the shared IMSL libraries that you would need to copy the IMSL DLLs onto that system. You are permitted to do so, with minor restrictions, by the license.

I'll try this version to see if there's a difference. I will comment that I am using the IMSL from version 11 - I don't have the older one installed anymore.
0 Kudos
g_f_thomas
Beginner
1,698 Views
Quoting - akrallis

Hello Steve,

I have attached the Fortran dll project. Please note that when the C# project runs on a PC whereFortean withimsl productare installed, everything runs without a problem. On the other hand when we use the C# project on a computer with the Visual Studio 2008 (without Fortran and IMSL installed), we get the 'Unable to load DLL error'.

Thank you in advance

Isn't this a surreptitiously naked attempt to provide IMSL functionality to someone who hasn't a legitimate license? VNI are a clever bunch who rightly protect their technology.

Gerry
0 Kudos
Steven_L_Intel1
Employee
1,698 Views
I don't see that from what's been supplied. You are correct that simply providing a wrapper to IMSL for the use of developers not licensed for it violates the IMSL EULA. But calling IMSL from your own DLL isn't necessarily a problem as long as you are adding value.
0 Kudos
g_f_thomas
Beginner
1,698 Views
I don't see that from what's been supplied. You are correct that simply providing a wrapper to IMSL for the use of developers not licensed for it violates the IMSL EULA. But calling IMSL from your own DLL isn't necessarily a problem as long as you are adding value.

The posted rar has no added value. It works if you distribute the IMSL licence though I wouldn't counsel that, but you never know, YMMV.

Gerry
0 Kudos
akrallis
Beginner
1,698 Views
I would expect that if you linked to the shared IMSL libraries that you would need to copy the IMSL DLLs onto that system. You are permitted to do so, with minor restrictions, by the license.

I'll try this version to see if there's a difference. I will comment that I am using the IMSL from version 11 - I don't have the older one installed anymore.

Hi Steve,

Have you tested the application under Fortran v10.1.025? Do you recommend to upgrade to Fortran v11?

Thank you in advance
0 Kudos
Reply