Community
cancel
Showing results for
Did you mean:
Novice
128 Views

## Pointer Arithmetic

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?

1 Solution
Black Belt
122 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?

4 Replies
Black Belt
123 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?

Novice
110 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])

Black Belt
81 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.

Novice
59 Views

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