- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi
I'm using Intel Fortran 11 to create a Fortran-Call-C piece of code
I have problem when passing arguments by value from Fortran to C, and I was wondering if this may come from 2003 support issues in ifort 11
The fortran sends a single argument by value
ival=1 in CALL p_f_i_AMETest(ival)
but the C function get the adress instead of the value, and print
ival =1703488 in void AMETest(int ival)
many thanks for any tips !!
Laurent
This is my code
TestDLL.cpp
extern "C" TESTDLL_API void AMETest(int ival) {
printf("ival =%d\n",ival);
};
Main.f90
PROGRAM main
!DEC$ REAL:8
USE DLLinterface
CHARACTER*200:: dllname = 'TestDLL.dll'
Call Test(dllname)
END PROGRAM
DLLinterface.f90
MODULE DLLinterface
USE kernel32
USE, INTRINSIC:: iso_c_binding
ABSTRACT INTERFACE
SUBROUTINE f_i_AMETest(ival) BIND(C,name='AMETest')
use iso_c_binding, only: c_int
integer(c_int), VALUE :: ival
END SUBROUTINE f_i_AMETest
END INTERFACE
INTEGER(HANDLE):: handleDLL
PROCEDURE(f_i_AMETest), POINTER:: p_f_i_AMETest
TYPE(C_FUNPTR):: p_c_function
INTEGER(C_INTPTR_T):: addressCpointer
INTEGER(C_INT):: returnedValue
CONTAINS
SUBROUTINE Test(DLLname)
CHARACTER*200, INTENT(IN):: DLLname
TYPE(C_FUNPTR):: p_c_function
INTEGER(C_INTPTR_T):: addressCpointer
INTEGER(C_INT):: returnedValue
INTEGER(C_INT):: ival
ival=1
handleDLL = LoadLibrary(DLLname)
IF (handleDLL == NULL) THEN
WRITE(*,*) 'DLLinterface: could not import the DLL'
ELSE
WRITE(*,*) 'DLLinterface: DLL imported'
END IF
addressCpointer = GetProcAddress(handleDLL, &
'AMETest')
!cast address to a c fonction pointer, then fortran
CALL C_F_PROCPOINTER( &
TRANSFER(addressCpointer,p_c_function), &
p_f_i_AMETest)
CALL p_f_i_AMETest(ival)
END SUBROUTINE Test
END MODULE DLLinterface
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't have an 11.x compiler available to try this myself, but let me suggest this:
Try adding an explicit %VAL() in your call, as: CALL p_f_i_AMETest(%val(ival))
if that gives a compile-time error, let's try using the non-standard directive in the abstract routine declaration:
!DEC$ ATTRIBUTES VALUE :: ival
--Lorri
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are using a compiler that is some seven (or more!) years old. I have a vague recollection of an old issue with VALUE not being recognized from an ABSTRACT INTERFACE. Please try it with a current compiler (version 17 is current.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Doctor Fortran !
Yes I know that my version is old, but I have no other release available right now (and not sure we will buy a new one or update just for the topic I am currently working for)
Any workaround possible in this case ? I really need to load a DLL because this piece of code have to be integrated in an another process.
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't have an 11.x compiler available to try this myself, but let me suggest this:
Try adding an explicit %VAL() in your call, as: CALL p_f_i_AMETest(%val(ival))
if that gives a compile-time error, let's try using the non-standard directive in the abstract routine declaration:
!DEC$ ATTRIBUTES VALUE :: ival
--Lorri
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Great ! it has worked !
I need to run more tests with other functions and more arguments, but I'm on the good way now :)
Many thanks Lorri :)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page