- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have successfully called a C routine in a dll from Fortran and a Fortran routine in a dll called from VB many times. This is the first time I've tried using VB to call Fortran to call C.
The simple test routines below try to pass an integer from a Fortran routine called by VB to a C routine.
The value being passed = 12, but when it reaches the C routine, the value = 1239536.
Suggestions?
VB 2010 code:
Declare Sub TEST_FTN Lib "LHM_Fsrc.dll" ()
Call TEST_FTN()
FTN code:
SUBROUTINE TEST_FTN()
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL :: TEST_FTN
!DEC$ ATTRIBUTES ALIAS:'TEST_FTN' :: TEST_FTN
IMPLICIT NONE
INTERFACE
SUBROUTINE Test_Int(i1)
!DEC$ ATTRIBUTES DLLIMPORT :: Test_Int
!DEC$ ATTRIBUTES DECORATE, ALIAS:'Test_Int' :: Test_Int
INTEGER :: i1
END SUBROUTINE Test_Int
END INTERFACE
INTEGER :: i1
i1 = 12
CALL Test_Int(i1)
RETURN
END SUBROUTINE TEST_FTN
C code:
__declspec(dllexport) void Test_Int(long i1);
void Test_Int(long i1)
{
long i2;
i2 = i1;
}
Regards, Mike
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You've told C that i1 is being passed by value, but Fortran thinks it is by refrerence. You could fix this by any of the following (in my decreasing order of preference):
1. Change the Fortran declaration of Test_Int to use the C interoperability features and the VALUE attribute:
INTERFACE
SUBROUTINE Test_Int(i1) BIND(C,NAME="Test_Int")
!DEC$ ATTRIBUTES DLLIMPORT :: Test_Int
INTEGER, VALUE :: i1
END SUBROUTINE Test_Int
END INTERFACE
2. Add the following directive to the interface body:
!DEC$ ATTRIBUTES VALUE :: i1
I want to point out that the VALUE attribute in 1 above, if you didn't have BIND(C), is not equivalent to ATTRIBUTES VALUE. With BIND(C), it is - at least in this case.
3. Change the C code to accept the argument by reference (*i1 in the prototype) and dereference it in the code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Steve,
Following your #1 preference works for me.
How would you change the following Fortran code which passes a character string to a C routine, or would you?
Fortran code:
SUBROUTINE TEST_FTN(choice, fname_)
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL :: TEST_FTN
!DEC$ ATTRIBUTES ALIAS:'TEST_FTN' :: TEST_FTN
!DEC$ ATTRIBUTES REFERENCE :: fname_
IMPLICIT NONE
INTERFACE
SUBROUTINE C_Routine(iChoice, FileName)
!DEC$ ATTRIBUTES DLLIMPORT :: C_Routine
!DEC$ ATTRIBUTES DECORATE, ALIAS:'C_Routine' :: C_Routine
INTEGER, VALUE :: iChoice
CHARACTER(LEN=256) :: FileName
!DEC$ ATTRIBUTES REFERENCE :: FileName
END SUBROUTINE C_Routine
END INTERFACE
!Type call list variables
INTEGER, INTENT(IN) :: choice
CHARACTER(LEN=256), INTENT(IN) :: fname_
! Type local variables
CHARACTER(LEN=256) :: fname
INTEGER :: i
fname = ' '
fname(1:255) = fname_(1:255)
i = LEN_TRIM(fname)
fname(i+1:i+1) = CHAR(0)
CALL C_Routine(choice, fname)
RETURN
END SUBROUTINE TEST_FTN
C code:
__declspec(dllimport) void C_Routine (int iChoice, char *FileName);
void C_Routine(int iChoice, char *FileName)
{
....
}
Regards, Mike
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
INTERFACE
SUBROUTINE C_Routine(iChoice, FileName) BIND(C,NAME="C_Routine")
USE, INTRINSIC :: ISO_C_BINDING
!DEC$ ATTRIBUTES DLLIMPORT :: C_Routine
INTEGER(C_INT), VALUE :: iChoice
CHARACTER, DIMENSION(*) :: FileName
END SUBROUTINE C_Routine
END INTERFACE
The standard makes an exception in this case for the rule about passing a scalar to an array.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'll need to study that a bit.
Thanks Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, I'll build one and post it Sergey

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