Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

Using C# class library in Fortran

sjors
Beginner
2,197 Views
Dear Formula Translators,

I have created a c# class library with which I can create/write etc to Access databases. Now I want to create a Fortran library that "translates" this dll, so it can be used by my collegues using Fortran only. Does anybody have a workaround? Should I do more in C# than simply creating a Class that is called Mdb which contains methods to e.g. open an access database? (The other way around I had to use dllimport statements to import a FortranDll in C#).

Cheers Arjen
0 Kudos
7 Replies
Steven_L_Intel1
Employee
2,197 Views
You may find that the Fortran Module Wizard helps here - it will read a .NET assembly or type library DLL and create a Fortran module with interfaces. How well it works for you depends on how you coded the C#. I have never used it for this purpose so can't provide specifics, but start by reading the documentation on the Module Wizard.
0 Kudos
sjors
Beginner
2,197 Views

Dear Steve,

Thank you for your answer, this helped a lot.I managed to get it working, after quite some trial and errors. I first had to add some interfaces to my c# code, andhave the"Generate code that uses Automation Interfaces" box checked. Otherwise functions are created witharguments of integer type only, whereas I also use floats/doubles/strings.

There seems to be one problem left. When I try to call a subroutine with arrays as arguments, the corresponding c# method is not called at all. If I change my c#-method to no arrays it works fine. I don't understand why it fails. The generated Fortran-code seems fine to me. Below follows an example which writes real(4) values to a column in a access database table. Do you see any problems in the code?

Thanks for helping me in advance!

Cheers Arjen

C#-interface:

void

WriteDataSP(string tableName, string columnName, float[] varValues);

generated Fortran-code:

SUBROUTINE iMdb_WriteDataSP($OBJECT, tableName, columnName, varValues, $STATUS)

IMPLICIT NONE

INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer

!DEC$ ATTRIBUTES VALUE :: $OBJECT

CHARACTER(LEN=*), INTENT(IN) :: tableName ! BSTR

CHARACTER(LEN=*), INTENT(IN) :: columnName ! BSTR

REAL(4), DIMENSI ON(:), INTENT(IN) :: varValues ! (SafeArray)

!DEC$ ATTRIBUTES REFERENCE :: varValues

INTEGER(4), INTENT(OUT), OPTIONAL :: $STATUS ! Method status

!DEC$ ATTRIBUTES REFERENCE :: $STATUS

INTEGER(4) $$STATUS

INTEGER(INT_PTR_KIND()) invokeargs

invokeargs

= AUTOALLOCATEINVOKEARGS()

CALL AUTOADDARG(invokeargs, '$ARG1', tableName, AUTO_ARG_IN, VT_BSTR)

CALL AUTOADDARG(invokeargs, '$ARG2', columnName, AUTO_ARG_IN, VT_BSTR)

CALL AUTOADDARG(invokeargs, '$ARG3', varValues)

$$STATUS

= AUTOINVOKE($OBJECT, 1610743813, invokeargs)

IF (PRESENT($STATUS)) $STATUS = $$STATUS

CALL AUTODEALLOCATEINVOKEARGS (invokeargs)

END SUBROUTINE iMdb_WriteDataSP

0 Kudos
Steven_L_Intel1
Employee
2,197 Views
I'll admit that my understanding of COM and automation is tenuous. I don't see anything obvious here, but have you checked the value of the $STATUS return?
0 Kudos
sjors
Beginner
2,197 Views

I checked the $STATUS and it is a very negative number, indicating it didn't work. A workaround would be not to use arrays, but it should be possible somehow. Maybe my c#-class is not properly defined? It works fine in c# though...Do you oranybodyelse have an example of a dll in which arrays work using code from the Module Wizard?

Cheers Arjen

0 Kudos
Steven_L_Intel1
Employee
2,197 Views
The provided COMAUTODICE sample does this, but I am not sure if it is directly applicable to your situation.
0 Kudos
g_f_thomas
Beginner
2,197 Views

C# and Fortran arrays differ in that they are 0- and 1- basedand are the transposes of each other.

It is possible to export from a C# DLL so that its classes can be accessed by unmanaged clients (Fortran, VC++,...) via the Windows API's LoadLibrary and GetProcessAddress and the use of pointers. Basically you disassemble the managed DLL without exportsvia ILDASM, edit the IL code to apply VT fixups, specify names of exports and their order in the VT, and reassemble the edited IL via ILASM to produce a new copy of the DLLwith exports. This is trivial to do but tedious. I've attached a zip with the before and after DLL's. Open them up with the Depends utility to observe their difference. MathFunctions.Dll is the managed while MF.Dll is also managed but has unmanaged exports.

Gerry

0 Kudos
sjors
Beginner
2,197 Views
I looked at your two versions of the dlls and found a good example to disassemle and reassemble my own dll in the way you said. Furthermore I used to DLL sample as an example to load the library and get the process addresses. However, I get exceptions when I try to call a function or subroutine. I also tried your dll in this way, and that works fine so there is probably still a problem in my C#-code. For now I have a working Fortran library using methods without arrays. Thanks for all the help and advice!

Cheers Arjen
0 Kudos
Reply