- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am new to Fortran and have to build an interface between C# and Fortran for that. The passing of the argument from C# to Fortran works without problems, but the easier task, passing values inside the Fortran-code does not want to work...
When I want to pass parameters from one Fortran function to another, in this case from VdiFunctionRunner to TGA_810, the called function does not have the correct paramter-values.
This is a stripped down version of my code:
[fortran]module VdiFunctionRunnerMain implicit none contains integer function VdiFunctionRunner (inXTGA, vdiCwertCllbak, vdiIwertCllbak, vdiRwertCllbak, vdiCwert2Cllbak, vdiIwert2Cllbak, vdiRwert2Cllbak, vdiErsterCllBak, vdiLetzterCllBak, vdiTestFuncCllBak) !DEC$ ATTRIBUTES DLLEXPORT, StdCall :: VdiFunctionRunner !DEC$ ATTRIBUTES REFERENCE :: inXTGA, vdiCwertCllbak, vdiIwertCllbak, vdiRwertCllbak, vdiCwert2Cllbak, vdiIwert2Cllbak, vdiRwert2Cllbak, vdiErsterCllBak, vdiLetzterCllBak, vdiTestFuncCllBak implicit none external vdiCwertCllbak, vdiIwertCllbak, vdiRwertCllbak, vdiCwert2Cllbak, vdiIwert2Cllbak, vdiRwert2Cllbak, vdiErsterCllBak, vdiLetzterCllBak, vdiTestFuncCllBak CHARACTER (256) :: inXTGA, copyXTGA CHARACTER (256) :: ARRAY_810(10), retValue, satzArt, satzArt2 CHARACTER (256) :: cWertCallBackRet copyXTGA = 'test' nrReturnValues = tga_810(copyXTGA, 1) return end function VdiFunctionRunner integer function tga_810(xtga, testNr) character (256), intent(in) :: xtga integer, intent(in) :: testNr return end function tga_810 end module VdiFunctionRunnerMain[/fortran]
As you see the passed values should be 'test' and 1, but in the debugger I get only the first character of the array ('t') and testNr = 0. I guess there is no error in writing the code, isn't it? When the code is correct, does somebody know if this can be a compiler problem or something like that?
I also wrote out the parameters to a file and I get the same values, so it can't be a problem of the debugger.
I am using the Intel 11 compiler.
Help is very much appreciated
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[bash] module VdiFunctionRunnerMain implicit none contains integer function VdiFunctionRunner () !DEC$ ATTRIBUTES DLLEXPORT, StdCall :: VdiFunctionRunner implicit none CHARACTER (256) :: inXTGA, copyXTGA CHARACTER (256) :: ARRAY_810(10) copyXTGA = 'test' nrReturnValues = tga_810(copyXTGA, 1) VdiFunctionRunner = nrReturnValues return end function VdiFunctionRunner integer function tga_810(xtga, testNr) character (256), intent(in) :: xtga integer, intent(in) :: testNr tga_810=2 end function tga_810 end module VdiFunctionRunnerMain[/bash]But I still have the same problem, so I do not think, that this is a problem of the calling conventions.
[fortran][DllImport("VdiFunctionRunnerDll.dll", EntryPoint = "_VDIFUNCTIONRUNNERMAIN_mp_vdifunctionrunner@0", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern int VdiFunctionRunner()[/fortran]The Fortran-code also uses StdCall.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For grins, you could quickly change your C and Fortran switches to use /iface:cref, /names:lowercase and /assume:underscore, and give it a try. If it works, you have a problem with your stdcall.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If that variable had an inconsistent declaration then you could get surprising behaviour. For what its worth, after I fixed that error and provided a little C# main function, your code "worked for me" with 12.1.1.
Compiler options and the target platform (x86/Intel 64) will influence this sort of stuff - consider posting the build log to provide that sort of information. The stack corruption that anthony mentions can also be due to code that is relatively distant from the code that is executing when visible problems occur - any testing or posting of snippets needs to take that into account.
As jeremy_h implies, unless you have very strong reasons to the contrary, linking via the mangled name (and to a lesser extent, the default Fortran binding) is an invitation for future pain and suffering. As you are using C# you are are clearly not stuck with FORTRAN compilers, punched cards, etc, from the glorious days of yore, so consider using the F2003 C-interoperability features to make your life much safer. An example attached below, but note very well - I know absolutely nothing about C# so take it all with a grain of salt. For your original example you should also consider the calling convention that applies to the callbacks that you are passing (?) - that consideration may reveal some "strong reasons" as referred to at the start of this paragraph.
[csharp]using System; using System.Runtime.InteropServices; namespace csharp { class Program { [DllImport("fortran.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern int VdiFunctionRunner(); static void Main(string[] args) { System.Console.Write(VdiFunctionRunner()); } } } [/csharp]
[fortran]module VdiFunctionRunnerMain implicit none contains function VdiFunctionRunner () BIND(C, NAME='VdiFunctionRunner') & RESULT(my_result) !DEC$ ATTRIBUTES DLLEXPORT :: VdiFunctionRunner USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT CHARACTER (256) :: copyXTGA INTEGER(C_INT) :: my_result copyXTGA = 'test' my_result = tga_810(copyXTGA, 1) end function VdiFunctionRunner integer function tga_810(xtga, testNr) character(*), intent(in) :: xtga ! assumes length of actual argument integer, intent(in) :: testNr tga_810=2 end function tga_810 end module VdiFunctionRunnerMain [/fortran]

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page