- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
In the following code which is part of a C++/Fortran interface, I need to pass fortran pointers to various types, and see proper descriptors at the C++ level, then set those descriptors so that upon return, fortran will see the correct data. This code works only when qresult and temp are defined as specific type pointers but not with the polymorphic ones I am trying to use below. My intent is to associate a fortran pointer to a type or array from C++, and not to copy the contents. I would appreciate any input on a possible solution.
interface
subroutine tDBGet(ctx, query, qtype, qresult, err)
import ContextType
type(ContextType), intent(inout):: ctx
character(len=*), intent(in):: query
character(len=*), intent(in):: qtype
class(*), intent(inout):: qresult(:)
integer, intent(inout):: err
end subroutine
end interface
type DatabaseAccessType ! type contained within ContextType
procedure(tDBGet), pointer, nopass:: dbGet ! DB query function pointer to obtain database information
end type
integer function prDBGetPtrRefS(ctx, query, qtype, qresult)
!DEC$ ATTRIBUTES NO_ARG_CHECK :: qresult
use device,only: DeviceType
implicit none
type(ContextType), intent(inout):: ctx
character(len=*), intent(in):: query
character(len=*), intent(in):: qtype
class(*), pointer, intent(inout):: qresult ! works only with type(DeviceType), pointer, intent(inout):: qresult
class(*), pointer :: temp(:) ! works only with type(DeviceType), pointer, intent(inout):: temp(:)
call ctx%db%dbGet(ctx, query, qtype, temp, prDBGetPtrRefS)
! call ctx%db%dbGet(ctx, query, qtype, qresult, prDBGetPtrRefS)
qresult => temp(1)
end function
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Amendment, since I can't edit original post:
- Apologies for not using fortran enclosures, code looks like text
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I assume you are basing your C++ code on the array descriptor layout we document. That doesn't work for polymorphic types, I'm afraid. I would recommend passing C_LOC of items and dealing with them as straight data pointers in C++. Even with the enhancements coming in Fortran 2015 to C interoperability, polymorphic data is still off limits.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm not quite sure what you want to do. To help us understand, could you perhaps provide a snippet of the relevant C++ code?
Fortran pointers and C[++] pointers are (mostly) different beasts - and consequently they are not interoperable. Similarly Fortran polymorphic objects and C++ base type pointers or references are not interoperable. However Fortran does have a derived type that can be used to store a C pointer, and you can get the C address of certain Fortran objects (not polymorphic ones, but you can get around that by wrapping the polymorphic object in another type).
Sometimes it is sufficient to pass the C address of a Fortran object as an opaque token (a handle) to C[++] code and then use that token in calls back to Fortran to identify the relevant object in subsequent operations.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
Thank you for the suggestion, and I do indeed base my interface on the documented fortran descriptors. Will C_LOC(ptr) of a local pointer variable such as : type(DeviceType), pointer:: ptr return the location of the pointer descriptor? I know that those locations vary greatly depending on how the subroutine is defined. For normal subs they are not on the stack, and for recursive ones they are. Will C_LOC provide me with the current location of the descriptor the fortran sub will see upon return, or will I get a copy?
I also noticed that using the above code, the real pointer descriptor for a (:) pointer is one descriptor (with alignment) before the one passed to C++, so if I set the descriptor passed to C++, fortran will still end up with an undefined pointer/array. Any comments on how to set this in an official way without using anything undocumented that might change?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Ianh : Thanks for the idea of wrapping polymorpic types, however, the approach of using opaque types is not suitable in this case, since we need to set fortran pointers to external data, that can be quite large, and that may need also to be modified from C++. On the other hand, using a data-copy method would make this interface quite slow.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
C_LOC will give you the pointer to the data, not the descriptor. Do not do anything to change the descriptor passed by Fortran in your C++ code. Again, future features will give you some access to Fortran pointers, but again not for polymorphic.

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