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

Return string from Fortran Dll back to C#.

dongxun
Beginner
460 Views
Dear all:
My C# program need a string returned from a Fortran Dll.
The Fortran Dll is like this:

SUBROUTINE REDO(s)
!DEC$ ATTRIBUTES DLLEXPORT::REDO, C
CHARACTER*(*) s
!DEC$ ATTRIBUTES REFERENCE :: s
s = 'Let them talk, now!'C
END

And I use C# PInvoke to call it, the client code like this:

public class BackString
{
[DllImport(@"BackString.dll",
EntryPoint="REDO")]
public static extern void REDO(string output);
}

string output = "";
BackString.REDO(output);

When I call this, I got an NullReferenceException, can anybody here explain
why? and how could I return the string?

I also tried to return the value as "Return" but have the same problem. The
.NET Framework's PInvoke example to use C's return string works fine, but I
just can't make the Fortran work.

Thank everybody and hope I could get some reply.

Regards
Alex

0 Kudos
2 Replies
Jugoslav_Dujic
Valued Contributor II
460 Views
[This is carried over from (almost) dead newsgroup microsoft.public.fortran. For others' convenience, I'll copy the relevant parts of the discussion there]:


That compiles?
Shouldn't that be !DEC$ ATTRIBUTES C, DLLEXPORT::REDO instead?

| !DEC$ ATTRIBUTES DLLEXPORT::REDO, C

I'm not familiar with C#, but with the change above, the code will be equivalent (interchangeable with) to:

extern "C" void __cdecl redo(char* s)
{strcpy(s, "Let them talk, now!");}



Does it work now? If not, what are the errors?


Thank you Jugo, I know that in order to modify the string parameter and let the caller know the changes, the callee must accept a char** instead of char*, so could you tell me how could I let the Fortran REDO function accept a ** equivalent parameter?


No. In order to modify string parameter, it is sufficient that the callee accepts a char*. char** is required in cases when the callee must allocate/free/change the memory location of the string as well. It is possible to do it in Fortran, but it's kind of tweak and I woundn't elaborate now -- I doubt you need it.

Are you sure that string is really a C# match for char*? As I said, I'm not familiar with C# so I just guess, based on experience with other languages. Try searching this Forum for "C#" or "PInvoke". Probably someone else will come up with a solution as well.

Jugoslav

0 Kudos
Jugoslav_Dujic
Valued Contributor II
460 Views
For a future reference:


StringBuilder should be used for string out arguments. How about the
following in C# ?

public static extern void REDO(StringBuilder output);
....
StringBuilder sb = new StringBuilder(1024);
REDO(sb);
Console.WriteLine(sb);

0 Kudos
Reply