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

IVF 9.1 Refuses to stop passing string length

skylane69
Beginner
682 Views

I am currently porting over one of our codes from CVF 6.6 to IVF 9.1. In this code I call some routines that are in C++ dlls. Some of the arguments I pass are character strings. Below are the C++ function delaration and the FORTRAN interface block. In CVF this would have passed the string pointer with no string length. According to the documentation IVF is supposed to have this same behavior. However, when running the code it is passing the string length after each argument. What am I doing wrong?

__declspec

(dllexport) int __stdcall InitModel( char *DllPathStr, char *DataFileStr, char *InitFileStr, char *OutFileStr, char *EngDesc )

INTERFACE
FUNCTION InitModel(DllPathStr, DataFileStr, InitFileStr, OutFileStr, EngDesc)

!DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'InitModel' :: InitModel
integer(4) InitModel

!DEC$ ATTRIBUTES REFERENCE :: DllPathStr
character*(*) DllPathStr
!DEC$ ATTRIBUTES REFERENCE :: DataFileStr
character*(*) DataFileStr
!DEC$ ATTRIBUTES REFERENCE :: InitFileStr
character*(*) InitFileStr
!DEC$ ATTRIBUTES REFERENCE :: OutFileStr
character*(*) OutFileStr
!DEC$ ATTRIBUTES REFERENCE :: EngDesc
character*(*) EngDesc

END FUNCTION
END INTERFACE

My external procedures compiler options (which shouldn't matter since I have overridden them all) are:

  • Calling convention: CVF
  • Name case interpretation: Upper Case
  • String length argument passing: After individual string argument
  • Append underscore to external names: no
  • Generate interface blocks: no

The string argument compiler option should be overridden by the STDCALL and REFERENCE attributes that I have specified in the interface block.

Ben

0 Kudos
3 Replies
Steven_L_Intel1
Employee
682 Views

I just tried an example and didn't see the behavior you describe. I took your INTERFACE and then called the named routine with five character arguments. Compiled with /iface:cvf (the other options are defaults for that). Only the addresses were passed, no lengths, and the decorated routine name ended with @20 as it should.

Are you sure the interface is being used? How are you determining that the lengths are passed?

0 Kudos
skylane69
Beginner
682 Views

Now that you mention it, it appears that my interface block isn't being used. I am seeing other behavior in my program as wellthat makes mepretty surethat it isn't being used. I'm not sure why my interfaces are beging ignored,the interface blocks are in the same module as the calling statementand are pointed to using a pointer statement. This arrangment worked fine in CVF, but it seems I need to make a change to get IVF to use the interface block. I'll look into it, but do you have any suggestions?

As for determining that string lengths are passed, when I step into the C++ code the first string argument is fine, but the second is invalid, then the third string argument in the C++ code is actually the second FORTRAN string, and so on. Also, if I change the default convention to pass lengths after all args then the strings work again, but this seems to be a poor way to mask the problem since there will be extra arguments on the stack for every call.

Ben

0 Kudos
skylane69
Beginner
682 Views

Thanks for your help. I had made a mistake insome other codechanges that were made to correct for some differences in the two compilers. Iwas able to move some pointer statements around and change a few other lines of code and it works fine now.

Thanks again.

Ben

0 Kudos
Reply