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

interoperability with C structs through c_f_pointer

damienhocking
New Contributor I
1,394 Views

All,

I'm having trouble accessing the members of a C struct that has an equivalent Fortran struct. The C struct is allocated over on the C side and the library returns a pointer to that struct back to the Fortran caller. I then use c_f_pointer to convert that to a Fortran pointer and attempt to access the contents of the Fortran struct, and when running this produces the error "Attempt to use pointer PVTPKGFORT when it is not associated with a target". I started running into this in our QC tests; it runs fine inside the Visual Studio debugger but in the console or QC scripts it throws the error.

This is the C struct, allocated and deallocated over in the C code:

struct MDLPVT_C
{
int numcomps_;
int numphases_;
};

The corresponding Fortran struct is:

type, bind(c) :: MDLPVT_C_FORT
integer(c_int) :: numcomps_
integer(c_int) :: numphases_
end type MDLPVT_C_FORT

The interface to the C function that allocates the C struct is:

function BuildPVT_C() result(pvt) bind(C, name="BuildPVT_C")
use, intrinsic :: ISO_C_BINDING
type(c_ptr) :: pvt
end function BuildPVT_C

 This sets the values of numcomps_ and numphases_ in the struct as well.

The (cut down) Fortran code is:

type(c_ptr) :: pvtpkg
type(MDLPVT_C_FORT), pointer :: pvtpkgfort

pvtpkg = BuildPVT_C()
call c_f_pointer(pvtpkg, pvtpkgfort)
write(*,*) 'Loaded PVT package'
write(*,*) 'PVT has ', pvtpkgfort%numcomps_, ' components'

Trying to access pvtpkgfort%numcomps_ is what produces the error.

Going through the Intel docs for c_f_pointer it says: "If the value of cptr is the C address of an interoperable data entity, fptr must be a data pointer with type and type parameters interoperable with the type of the entity. In this case, fptr becomes pointer-associated with the target of cptr." I thought that's what I've done, but obviously there's something missing.

I've tried adding the target attribute to pvtpkg and c_loc(pvtpkg) in the c_f_pointer call, which removes the error message in the console but then the pvtpkgfort struct member values are set to garbage. Do I need a shape argument in the c_f_pointer call?

This must be something simple. Can anyone tell me what I'm doing wrong?

Damien 

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
1,371 Views

If you're getting that error, it suggests to me that BuildPVT_C is returning a null pointer. You haven't shown us enough to be able to tell you for sure, but a debug session should make it obvious enough.

View solution in original post

0 Kudos
11 Replies
IanH
Honored Contributor II
1,389 Views

Please show the prototype of the C function.

What version of ifort are you running?

0 Kudos
damienhocking
New Contributor I
1,386 Views

Ian, the C prototype is:

MDLPVT_C* BuildPVT_C();

It returns the raw pointer, contained in a C++ unique_ptr kept in a catalog of structs, it hasn't been deleted. We use that catalog all through our software for the .NET and C APIs.

Intel version 2019.5.068, I have 2020 as well.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,332 Views

>>It returns the raw pointer, contained in a C++ unique_ptr 

I suggest you use the debugger to assure that the contained pointer within the unique_ptr is returned as opposed to the address of the unique_ptr itself.

Also, have you assured that the specific unique_ptr has not gone out of scope (been dtor'd).

Jim Dempsey

0 Kudos
damienhocking
New Contributor I
1,326 Views

Yeah, the exception is causing the pointer to get wiped, correctly, on a separate thread, so sometimes it's nulled and sometimes it isn't. I don't know why the exception doesn't show up in the IDE though (extra IDE training wheels maybe) but we have another test case now and a couple of bugs to fix.  

0 Kudos
Steve_Lionel
Honored Contributor III
1,321 Views

Debug > Windows > Exception Settings

This lets you tell the debugger to break on various exception types. Otherwise, it will break on unhandled exceptions only.

0 Kudos
damienhocking
New Contributor I
1,318 Views
0 Kudos
JohnNichols
Valued Contributor III
1,306 Views

Tha mi a ’moladh gun cleachd thu an dì-bhugadair gus dèanamh cinnteach gun tèid am puing a tha taobh a-staigh an uathúil_ptr a thilleadh an àite seòladh an uathúil_ptr fhèin.

I wanted to know if Jim's comment 

I suggest you use the debugger to assure that the contained pointer within the unique_ptr is returned as opposed to the address of the unique_ptr itself.

actually made more sense in Gaelic -- not quite but it is close -- I hate pointers they are a invention of the C gods and ruined Fortran 

0 Kudos
Steve_Lionel
Honored Contributor III
1,372 Views

If you're getting that error, it suggests to me that BuildPVT_C is returning a null pointer. You haven't shown us enough to be able to tell you for sure, but a debug session should make it obvious enough.

0 Kudos
damienhocking
New Contributor I
1,366 Views

Unfortunately, it's not. Is the Fortran code as I've written it there correct? If that's OK then I'll dig elsewhere. 

0 Kudos
Steve_Lionel
Honored Contributor III
1,357 Views

It looks OK to me, but as I often say, snippets, excerpts and pseudocode almost always hide the real problem.

0 Kudos
damienhocking
New Contributor I
1,352 Views

And, you would be right. I just found it. There's an exception being thrown from a third-party JSON library that the IDE catches and silently buries, but in console operation propagates up and makes a mess. It's not a Fortran/C interop problem, the code is right. Thank you for the help.

0 Kudos
Reply