- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear all,
I read may post in this forum about using C DLLs in Fortran programs. I'm stuck in a problem of basic operations (the main problem here is that I'm a very beginner in such things ....) in passing a string (defined as char) from a C to Fortran. In a C DLL I have this:
__declspec(dllexport) void getArr(char &out) { strcpy(&out, "hello"); }
and in a separate Fortran program this:
program FortranCallC implicit none interface subroutine getArr(a) bind(C, name="getArr") USE,INTRINSIC :: ISO_C_BINDING !DEC$ ATTRIBUTES REFERENCE :: a CHARACTER, DIMENSION(*), INTENT(INOUT) :: a end subroutine end interface CHARACTER(LEN=128) :: stringa call getArr(stringa) write(*,*)"->",trim(stringa),"<-" pause end program
The Fortran program displays a strange line in the write(*,*) statement, and, after many posts read and lot of hours wasted, I cannot figure out why. The string I get is like this:
-> hello <-
and I cannot trim() it. In the debugger (VS2013) I see many rectangular characters instead of the white spaces pasted here.
I'm sorry if this post could seem obvious, but the solution is hard to find for me.
Secondly, what if I decide to pass the pointer of the string? Can I make it work in the same way? I tried many ways but no success ...
Regards,
Giovanni
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What exactly are you trying? What is getArr function in C supposed to do?
Look into what C strcpy function does with null termination and the functioning of Fortran TRIM intrinsic with the presence of C null termination character in the actual argument variable.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If getArr is supposed to copy certain string information to the address received with blank padding to the right, I suggest you use sprintf function in C. Also, make the C function parameter a pointer to char and include the maximum number of characters to be copied in the parameter list, like so:
__declspec(dllexport) void getS(char * s, int lens) { sprintf(s, "%-*s", lens, "Hello"); }
program FortranCallC use, intrinsic :: iso_c_binding, only : c_char, c_ptr, c_int, c_loc implicit none interface subroutine getS(s, lens) bind(C, name="getS") import :: c_ptr, c_int implicit none !.. Argument list type(c_ptr), intent(in), value :: s integer(c_int), intent(in), value :: lens end subroutine getS end interface !.. Declarations character(kind=c_char,len=128), target :: s integer(c_int) :: lens !.. Begin execution lens = int( len(s), kind=kind(lens) ) call getS( c_loc(s), lens ) write(*,*)"->",trim(s),"<-" pause end program
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, the example provided works prefectly! Yes, getArr is supposed to copy certain string information to the address received with blank padding to the right.
Thanks also for the example with the pointer, just a couple of clarifications:
1. what c_loc stands for? We want the C address of the string s, right?
2. why lens must enter in getS with the lenght of 128? to reserve the memory space? (sorry, maybe this is common in C++, but I'm an absolute beginner on this language...)
thanks again
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In Fortran, character variables can have various lengths. The notion of a string as a sequence of characters terminated by a null character, which is used in C, does not exist in Fortran. The Fortran character constant 'abc' has length=3, for example but, In C, "abc" is 4 bytes long. There are Fortran rules for what to do when expressions contain character constants and variables of different lengths, and what happens when a character expression is assigned to a character variable of a different length than that of the expression.
When using C/Fortran interoperability facilities, the conventions of C and Fortran have to be reconciled, and the mechanics of doing so can be a bit perplexing when you encounter them for the first time.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks all for the replies.
Unfortunately, I have another problem: the code you suggested works fine in 32 bit, but in 64 bit the Intel Fortran compiler says that it cannot find the reference to symbol getS during FortranCallC compilation.
What's wrong? I think that in 64bit the integer memory usage id doubled, but I don't know how to change the code to make it work both in 32 and 64 bit.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How (describe in detail) are you compiling the C and the Fortran? Are you supplying the import library generated when compiling the C DLL when linking the Fortran executable?
(Note that if your objective is just to get Fortran and C code talking to each other within the same executable module, then you don't need to split the stuff for one particular language out into a separate DLL - DLL's are used for other reasons.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear IanH, many thanks for your reply. I have to say sorry: I believed that, when making a new configuration in VS, the "copy settings from" command will copy also target folder. My fault; now the executable works also when compiled in 64bit.
To leave a more valuable information into the forum to other people who'll read this in the future, previous answers allowed to me compile a C++ library (wrapper) with /clr support, that can communicate with a .NET DLL. My final aim is to use a .NET DLL in Fortran language.
I think that the main advantage of this solution rather than compiling the .NET DLL with COM support is that, with this approch, you're not obliged to register with regsvr and no TLB files to manage.

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