Passing strings to C++ from ifort 12

Passing strings to C++ from ifort 12

Hello,

In the following code snippet I notice that string lengths are passed to C++ differently:

type MyPro
character(len=256) :: path
end type 
subroutine Test
implicit none
type(MyPro):: Pro
character(len=256):: path 
integer::err
!these call directly C++ functions defined as
! void dbGet(const char *key, char *pValue, int *err, size_t key_len, size_t value_len)
!
call dbGet("Path", Pro%path, err) 
call dbGet("Path", path, err) 
end subroutine

The problem is that on the C++ side value_len gets a 0 value from the first fortran call, but the correct value from the second call.
 I would appreciate an explanation for this,

Thanks 

8 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

We need more details about how you compile and which compiler versions you use, as well as actual source code to demonstrate the problem. Using the attached files and IFort/Icl 13.1.1.171, in the debugger I see 4 and 256 inside DBGET for key_len and value_len during both calls to DBGET.

This looks like a calling mechanism problem since Fortran doesn't know anything about C++ - it just has a standard way to interface with C. Is your program 32 or 64 bit? As far as I know there is only one calling convention on 64-bit whereas there is a whole plethora of them in 32-bit. I believe the standard is now to have a 1:1 correspondence between Fortran and C argument lists - no more hidden arguments. So with the right calling convention (or in 64-bit) you should be able to do

call dbGet("Path", Pro%path, err, len("Path"), len(Pro%path))

I seem to be unable to post the full text of my update here, so I attach it as a text file.
Please download and read,

Thanks 

Attachments: 

AttachmentSize
Downloadtext/plain intel.txt3.06 KB

In your case 2 (type embedded), the NULL char you observed after the string is likely accidental.

type MyPro 
character(len=256) :: path 
integer :: flag
end type

Initialize path as before, but set flag to -1.

Jim Dempsey

www.quickthreadprogramming.com

Thanks Jim, I checked with various stack data around the fortran type and it was indeed accidental. This leaves the #2 issue still unsolved.

I suggest that since your C++ side interface explicitly uses a size argument that you declare the C++ interface on the FORTRAN side with explicit size arguments as sgearg suggests.

Note, you can create a shell function in FORTRAN that is passed (key,value,err) which calls the C++ function with  (key,value,err, LEN(key), LEN(value)). Or use LENTRIM in place of LEN.

Jim Dempsey

www.quickthreadprogramming.com

Thanks everyone, I finally found a workaround without extra size arguments.since the general issue is to pass any type, array or string. My interface code depends on a custom data mining tool that extracts types from fortran files and their dependent embedded types (if any) and generates binary-compatible C++ structures. It also creates appropriate metadata describing each type, members, descriptors, sizes, etc. These structs have exactly the same size as the fortran types, so I use the metadata to extract the size of anything, including strings. I know, this deviates from my original question, but the issue was more general.

Leave a Comment

Please sign in to add a comment. Not a member? Join today