- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am trying to write to a C function that has two structs in it.
void func_name (structIn *In, structOut *Out)
the first struct takes input from the fortran program, the structOut passes data back to the fortran program.
i am really a little lost on what the fortan side of it should look like. I have this so far which i pieced together from some sample code.
INTERFACE
SUBROUTINE func_name (BLOCKIN, BLOCKOUT )
!DEC$ ATTRIBUTES C :: func_name
!DEC$ ATTRIBUTES REFERENCE :: BLOCKIN
!DEC$ ATTRIBUTES REFERENCE :: BLOCKOUT
INTEGER BLOCKIN
END SUBROUTINE
END INTERFACE
INTEGER G
INTEGER B
INTEGER T
INTEGER R
INTEGER C
INTEGER P
INTEGER V
INTEGER S
CHAR(10) STRING1
CHAR(10) STRING2
COMMON /BLOCKIN/G, B, T, R, C, P, V, S
COMMON /BLOCKOUT/ STRING1, STRING2
. . .
CALL func_name( CBLOCKIN, BLOCKOUT )
there are a lot of pieces where I am unsure about the code.
void func_name (structIn *In, structOut *Out)
the first struct takes input from the fortran program, the structOut passes data back to the fortran program.
i am really a little lost on what the fortan side of it should look like. I have this so far which i pieced together from some sample code.
INTERFACE
SUBROUTINE func_name (BLOCKIN, BLOCKOUT )
!DEC$ ATTRIBUTES C :: func_name
!DEC$ ATTRIBUTES REFERENCE :: BLOCKIN
!DEC$ ATTRIBUTES REFERENCE :: BLOCKOUT
INTEGER BLOCKIN
END SUBROUTINE
END INTERFACE
INTEGER G
INTEGER B
INTEGER T
INTEGER R
INTEGER C
INTEGER P
INTEGER V
INTEGER S
CHAR(10) STRING1
CHAR(10) STRING2
COMMON /BLOCKIN/G, B, T, R, C, P, V, S
COMMON /BLOCKOUT/ STRING1, STRING2
. . .
CALL func_name( CBLOCKIN, BLOCKOUT )
there are a lot of pieces where I am unsure about the code.
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You almost got it -- you should pass G and STRING1 to func_name. G and STRING1 are the first members of corresponding COMMONs -- I don't think you can use COMMON name anywhere in Fortran anywhere where context requires a variable. Oh yes, you should declare STRING1 as CHARACTER(*) within the INTERFACE block as well.
Note that you can match C prototype with TYPEs instead of COMMONs*; I like that approach more, since it provides richer capabilities (for example, you can declare more variables of appropriate TYPE but you'd have to write a new COMMON for each variable set) and is more semantically equivalent with C routine.
Jugoslav
----
* This involves some tricky scoping issues -- see this comp.lang.fortran thread
Note that you can match C prototype with TYPEs instead of COMMONs*; I like that approach more, since it provides richer capabilities (for example, you can declare more variables of appropriate TYPE but you'd have to write a new COMMON for each variable set) and is more semantically equivalent with C routine.
Jugoslav
----
* This involves some tricky scoping issues -- see this comp.lang.fortran thread
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Oh yes, you should declare STRING1 as CHARACTER(*) within the INTERFACE block as well.
Obviously, that should be BLOCKOUT, not STRING1.
Obviously, that should be BLOCKOUT, not STRING1.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jugoslavdujic,
you wrote this "Note that you can match C prototype with TYPEs instead of COMMONs*; " can you elaborate on this just a little, im not sure what you mean. Im not the most experienced Fortran programmer...
Also, everything seems to compile alright now, except that i get the message error LNK2001: unresolved external symbol func_name when i put in a call to the function.
call func_name ( g, string1)
Any ideas?
thanks for the help
you wrote this "Note that you can match C prototype with TYPEs instead of COMMONs*; " can you elaborate on this just a little, im not sure what you mean. Im not the most experienced Fortran programmer...
Also, everything seems to compile alright now, except that i get the message error LNK2001: unresolved external symbol func_name when i put in a call to the function.
call func_name ( g, string1)
Any ideas?
thanks for the help
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Re link error: func_name should be declared extern "C" in C code (in both .h file and .cpp file, prepend the function prototype with extern "C").
Re derived types: the following is semantically equivalent to your sample:
The advantage is that you can have as many BlockXXX variables as you want.
Jugoslav
Re derived types: the following is semantically equivalent to your sample:
MODULE MyMod TYPE T_Blockin SEQUENCE REAL G REAL H ... END TYPE T_Blockin TYPE T_Blockout SEQUENCE CHARACTER(10) String1 CHARACTER(10) String2 END TYPE T_Blockout END MODULE MyMod !================ ... Use MyMod INTERFACE SUBROUTINE func_name(Blockin, Blockout) !DEC$ATTRIBUTES C:: func_name !DEC$ATTRIBUTES REFERENCE:: Blockin !DEC$ATTRIBUTES REFERENCE:: Blockout USE MyMod !That's the tricky scoping part TYPE(T_Blockin):: Blockin TYPE(T_BlockOut):: Blockout END SUBROUTINE END INTERFACE TYPE(T_Blockin):: Blockin !If you need these global, TYPE(T_BlockOut):: Blockout !put them in MyMod BlockIn%G = ... CALL func_name(Blockin, Blockout) WRITE(*,"(A,1x,A)") Blockout%String1, Blockout%String2
The advantage is that you can have as many BlockXXX variables as you want.
Jugoslav

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