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

Pointer problem in mixed language programming

jaeger0
Beginner
387 Views
I have Problems using a linked-list structure PAT_lst, which I use in Fortran and C.


I have the following structures in Fortran

type, BIND(C):: PAT_inf
character(TYP_PN) name ! PN patient name
character(TYP_LO) id ! LO patient iD
character(TYP_DA) birth ! DA patient birth
character(TYP_CS) sex ! CS patient sex
character(TYP_AS) age ! AS patient age

integer(TYP_IS) nStd ! IS NumberOfPatientRelatedStudies
integer(TYP_IS) nSer ! IS NumberOfPatientRelatedSeries
integer(TYP_IS) nIns ! IS NumberOfPatientRelatedInstances
end type

type:: PAT_it
type(PAT_inf) item
type(PAT_it), pointer:: next
type(PAT_it), pointer:: prev
end type
type:: PAT_lst
type(PAT_it),pointer:: list_top
type(PAT_it),pointer:: list_bot
integer(TYP_IS) nPat
end type

with the global variable type(PAT_lst) PatList;

I call the C-subroutine with

SUBROUTINE call_findscu (p_res,pacs_opt, PatList, debug,verbose)
use PACS_DEF
! Specify C calling and naming conventions
!DEC$ ATTRIBUTES C :: call_findscu
INTEGER, INTENT(IN) :: debug,verbose
type(PAT_lst) PatList
type(PACS_RES) p_res
type(PACS_CONF) pacs_opt
! Specify that the CHARACTER arguments are by reference
! with no hidden length
!DEC$ ATTRIBUTES REFERENCE :: p_res,pacs_opt, PatList
END SUBROUTINE call_findscu


the C-structures are:
PAT_lst PatList; // the dynamic patient list

struct PAT_lst{
struct PAT_it *list_top; // top of patient list
struct PAT_it *list_bot; // bottom of patient list (last item inserted)
int nPat; // number of patients in list
};


with the C- function

extern "C" void call_findscu(PACS_RES *p_res, PACS_CONF *pacs_opt, PAT_lst *iPatList, int debug, int verbose) {
FILE *o_file;
filebuf out_file;
filebuf err_file;

PatList = *iPatList;
PAT_lst_Init(PatList); // initialize patient list
...

here I add items to the dynamic list, and all works.

However back in the Fortran subroutine PatList, is vieable, with the debugger ( all items), but I cannot acess the values, for example
item => PatList%list_top, results with undefined pointer for item, even for the debugger PatList%list_top is viewable

Is there any problems using this datatypes ? For the structure PAT_lst I can not use the BIND(C), option, like for type, BIND(C):: PAT_inf

Any guess what the Problem could be ?
0 Kudos
5 Replies
TimP
Honored Contributor III
387 Views
I would have thought C_F_POINTER would be required to make a Fortran copy of the pointer.
0 Kudos
jaeger0
Beginner
387 Views
Hmm, now it works.
The problem was in the C-source, where I had to replace the definition of
PAT_lst PatList; by PAT_lst *PatList;

but Have I to use

CALL C_F_POINTER(PatList%list_top, item)

instead of

item => PatList%list_top

for me works, at the moment the second expression. Is this correct ?
0 Kudos
Jugoslav_Dujic
Valued Contributor II
387 Views
The bottom line: you can, but you don't have a guarantee for it. Intel's implementation of the scalar POINTERs happens to be interoperable with C pointers, but it may change in the future, or if you change the compiler.

I've also been bitten using Fortran POINTERs as arguments or results of BIND(C) functions in 11.1. When 12.0 came, I had to say goodbye. The difference with your case is that the Standard explicitly forbid it (but 11.1 didn't bother to check), while you're outside of the standard's scope (no Bind(C), no checking).

So, if you're in pedantry mood, change the code. In my case, it wasn't cheap at all, so I was forced to switch back to !DEC$ATTRIBUTES for interoperability.
0 Kudos
JVanB
Valued Contributor II
387 Views

type, BIND(C):: PAT_inf
character(TYP_PN) name ! PN patient name

ifort doesn't catch this?
0 Kudos
jaeger0
Beginner
387 Views
no problem with this
0 Kudos
Reply