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

Pointer Arithmetic

Nick3
New Contributor I
1,130 Views

I know how to do all this in C, but not in Fortran.

I realize this is a far-fetched solution that may or may not work, but here it goes.

I have this well defined:

REAL,POINTER :: HIJACKSTUFFREAL(:)

I also have:

TYPE(C_PTR) voidstar

INTEGER, POINTER :: IPTR(:)

For now, I managed to do this successfully:

voidstar = C_LOC(HIJACKSTUFFREAL)

What I need to do now is:

IPTR is a pointer of size (12345) at the address voidstar + z'1F48FCE0' - z'1F4D16E0'

How do I do that?

0 Kudos
1 Solution
IanH
Honored Contributor II
1,124 Views

Why are you trying to do this? 

 

(Check the variable names in your post.)

 

You can convert from the C address stored in a C_PTR object to an integer value of kind C_INTPTR_T using TRANSFER.  You can do arithmetic with integers.  You can convert back again using TRANSFER.  You can associate the object at the C address stored in a C_PTR object and a Fortran pointer using the C_F_POINTER procedure.

 

Be mindful whether your arithmetic/offsets/sizes are in bytes or size-of-the-scalar-object-being-pointed-at.

 

Knowing that the storage size of default real and integer are the same, and knowing the storage size of a default real can be queried by the STORAGE_SIZE intrinsic, you can probably skip all the C pointer conversion and just apply TRANSFER to the relevant array element.

 

But... why?

View solution in original post

0 Kudos
4 Replies
IanH
Honored Contributor II
1,125 Views

Why are you trying to do this? 

 

(Check the variable names in your post.)

 

You can convert from the C address stored in a C_PTR object to an integer value of kind C_INTPTR_T using TRANSFER.  You can do arithmetic with integers.  You can convert back again using TRANSFER.  You can associate the object at the C address stored in a C_PTR object and a Fortran pointer using the C_F_POINTER procedure.

 

Be mindful whether your arithmetic/offsets/sizes are in bytes or size-of-the-scalar-object-being-pointed-at.

 

Knowing that the storage size of default real and integer are the same, and knowing the storage size of a default real can be queried by the STORAGE_SIZE intrinsic, you can probably skip all the C pointer conversion and just apply TRANSFER to the relevant array element.

 

But... why?

0 Kudos
Nick3
New Contributor I
1,112 Views

Excellent, I had to make  C_INTPTR_T a POINTER, but it's working great!

Well, we have to access a non-exported COMMON block in a DLL; we can look at this DLL, but can't really touch it.

Are you saying, something like this?

CALL C_F_POINTER(HIJACKSTUFFREAL+ offset in REALs rather than offset in bytes, IPTR, [ISIZE])

0 Kudos
IanH
Honored Contributor II
1,083 Views

The INTEGER(C_INTPTR_T) would not have to be a POINTER.  If you think it does, show your code.

I thought your real array would cover the entire common block.  I see now that your offset would be a negative index beyond the start of that array.  Never mind.

0 Kudos
Nick3
New Contributor I
1,061 Views

It crashed yesterday when I tried just INTEGER(C_INTPTR_T).  It doesn't crash today.

0 Kudos
Reply