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

Correct C++ / Fortran Interfaces

jaeger0
Beginner
305 Views
I have a main code in Fortran which calls a C++ code (compiled DLL). However sometimes the values of the data-structures are not correct in the fortran code.

In Principle I have a C++ code, which fills up a dynamic list (FIL_lst), running in a thread.
In another Fortran thread I'm waiting and processing the FIL_list, however, for example the parameter processed is set to 0 in C++ but readed out with in the fortran code with processed = 892614965. I pass the FilList by reference to the C++ program. Does anyon know what's the reason for this problem ? The other arguments of FIL_it are passed correctly.

C++ definitions:

struct FIL_it{ // File item
char fname[TYP_FILEN]; // the file-name
int processed; // 0.. not processed, 1.. processed
struct FIL_it *next; // next item
struct FIL_it *prev; // previous item
};
struct FIL_lst{
struct FIL_it *list_top; // top of file list
struct FIL_it *list_bot; // bottom of file list (last item inserted)
int locked; // 0.. list free, 1.. list locked (by another process)
int nFiles; // number of files in list
};
extern FIL_lst *FilList;


Fortran definitions:

integer,parameter:: TYP_PN = 64
integer,parameter:: TYP_IS = 4



type FIL_it
character(TYP_PN) fname
integer(TYP_IS) processed ! 1.. file was already processed, 0.. file was not processed yet
type(FIL_it), pointer:: next
type(FIL_it), pointer:: prev
end type
type FIL_lst
type(FIL_it),pointer:: list_top
type(FIL_it),pointer:: list_bot
integer(TYP_IS) locked ! 0.. list free, 1.. list locked (by another process)
integer(TYP_IS) nFiles ! number of files in list
end type

type(FIL_lst),pointer:: FilList;

0 Kudos
2 Replies
joerg_kuthe
Novice
305 Views

Have you checked the alignment of data in your structure? It may be that your C++ uses 8-byte alignment ( #pragma pack(8);structure components are aligned on 8-byte boundaries) and Fortran's default setting is 1-byte alignment (structure components are "packed"). Try the following:

Add a metadirective to your TYPE definitions.
!DEC$ ATTRIBUTES ALIGN: 8 :: FIL_it,FIL_lst

Also, I think it advisable to make sure that your TYPE's components are ordered in memory as defined (use SEQUENCE). For example:

type FIL_it
SEQUENCE
character(TYP_PN) fname
integer(TYP_IS) processed ! 1.. file was already processed, 0.. file was not processed yet
type(FIL_it), pointer:: next
type(FIL_it), pointer:: prev
end type
!DEC$ ATTRIBUTES ALIGN: 8 :: FIL_it,FIL_lst

Let us know, if this cures your problem.

Joerg Kuthe
www.qtsoftware.com

0 Kudos
JVanB
Valued Contributor II
305 Views
If you want your Fortran user-defined types to interoperate with C structs, a good start would be to give them the BIND attribute, e.g. type, BIND(C) :: FIL_it.Then the compiler should catch your attempt to match type(FIL_it), pointer :: next with struct FIL_it *next. On the Fortran side you needed type(C_PTR) next because a Fortran pointer is normally not just a simple address and so won't occupy the same space as a C pointer. To make that go, you will also need to USE the intrinsic ISO_C_BINDING module and at that point you could make TYP_IS = C_INT and also check that TYP_FILEN = 64 in your C code. You will probably have to change character(TYP_PN) fname to character(kind=C_CHAR) fname(TYP_PN) after the above changes which implies altering your usage of the fname structure component, but at least your udt will be interoperable.
0 Kudos
Reply