- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I've been trying to port some CVF code to Intel Fortran and I ran into the same problem that was solved at: http://software.intel.com/en-us/forums/topic/279785
I attempted to implement the solution Steve posted, but I am getting accesss violation errors.
In my Interface I have:
MODULE SERVICE_INTERFACE
IMPLICIT NONE
INTERFACE
SUBROUTINE saveResult(ARGS)
!DEC$ ATTRIBUTES DLLIMPORT,STDCALL :: saveResult
!DEC$ ATTRIBUTES DECORATE, ALIAS:'saveResult' :: saveResult
!DEC$ ATTRIBUTES REFERENCE :: ARGS
END SUBROUTINE saveResult
END INTERFACE
END MODULE SERVICE_INTERFACE
And in my subroutine I have:
INTEGER(handle) :: P
INTEGER(C_INTPTR_T) :: q1
P = loadlibrary("Service.dll"C)
IF(P == 0) THEN !Error Processing
q1 = getprocaddress(P,"_saveResult@4"C)
if(q1 == 0)then !Error Processing
CALL C_F_PROCPOINTER(TRANSFER(q1,C_NULL_FUNPTR), saveResult)
CALL saveResult(ARGS)
I don't have the option to recompile the C++, but that's not the issue because this worked in CVF. How can I make the call work? Also, does anyone have any suggestion on how I can replace the ATTRIBUTES in the interfaces with the BIND() function? I can't make the linker work using BIND().
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
By the way, I am using Intel Visual Fortran Composer XE 2013 Update 2
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You're missing some code from your excerpt here. How is SaveResult declared in the subroutine? In the subroutine, you need to declare a procedure pointer to be used in the call to C_F_PROCPOINTER, and it has to be declared as having the interface you defined in the module. Practically speaking, these can't have the same name.
Can you work up a complete example that demonstrates the problem? Provide a dummy C++ routine it uses. There's too much missing from your post to help you.
As for your question on BIND(C), sorry, you can't use that right now to call a STDCALL routine.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My source code was missing the procedure pointer. Now I have:
[fortran]
MODULE SERVICE_INTERFACE
IMPLICT NONE
INTERFACE
SUBROUTINE saveResult(ARGS) BIND(C, NAME='saveResult')
!DEC$ ATTRIBUTES REFERENCE :: ARGS
END SUBROUTINE saveResult
END INTERFACE
END MODULE SERVICE_INTERFACE
[/fortran]
The subroutine has been changed to:
[fortran]
INTEGER(handle) :: P
INTEGER(C_INTPTR_T) :: q1
procedure(saveResult), pointer :: saveResult_callback
P = loadlibrary("Service.dll"C)
q1 = getprocaddress(P,"_saveresult@4"C)
CALL C_F_PROCPOINTER(TRANSFER(q1, C_NULL_FUNPTR), saveResult_callback)
CALL saveResult_callback(ARGS)
[/fortran]
This compiles and calls into the C++ dll correctly. I'm only concerned about still loading the process with the @n suffix, but using only saveResults in the BIND call.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry I can't come up with a more detailed example, I'm not allowed to have any c++ compilers on the machine I use for development and I don't know too much about the language.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This latest version will appear to work, but will corrupt the stack. Don't do it. The routine name from the interface is not used in the program you show here, but that the interface specifies the C convention and your routine is STDCALL will cause the stack to be double-popped on each call. Very bad things will happen in a real program that does this - you may not notice in a toy program.
As I wrote earlier, you cannot use BIND(C) here - you must use the ATTRIBUTES STDCALL, REFERENCE. The ALIAS and DECORATE can be removed as you're not using the name.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do you really need to use LoadLibrary here? Is there not an export library (.lib) from the DLL you can link against?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I changed my code to get rid of the BIND statement and use the attributes.
I'm actually loading several different libraries, some have .lib files, some don't. I'm guessing it's easier to just link against these. I'll have to explore that option. Thanks for your responses. I really appreciate the help.

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