- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, all.
I wrote some test code using C DLL in Fortran.
I tested the memory matching between Fortran TYPE and C structure.
MODULE mod
TYPE test_t
INTEGER a
INTEGER b
INTEGER,POINTER::c(:)
REAL d
INTEGER e
INTEGER f
INTEGER g
END TYPE
END MODULE mod
PROGRAM main
USE mod
IMPLICIT NONE
TYPE(test_t) input
input%a=1
input%b=2
ALLOCATE(input%c(2))
input%c(1)=3
input%c(2)=4
input%d=5.5
input%e=6
input%f=7
input%g=8
call TEST(input)
END PROGRAM main
I simply put some values in Fortran code, and check it in C code like below.
typedef struct _test_t
{
int a;
int b;
int* c;
float d;
int e;
int f;
int g;
} test_t;
extern "C" __declspec(dllexport) void TEST(test_t* member)
{
printf("%f",member->d);
}
Before the pointer, the value are all right (a=1,b=2,c[0]=3,c[1]=4), but after then the values are distorted.
d=5.605e-045#DEN
e=-4
f=5
g=1
I guess the size of pointer in Fortran and C is different.
Anybody knows how to solve this problem?
Thank you.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you compile 32 bit app, pointer size is 4 bytes does not matter on language.
I think that problem is that you use fortran pointer and not integer pointer. (I do not use fortran pointers so i do not have experience with this.
1. Are the values of a and b correct. if yes there is probably problem with c.
2. Try to put c at the end of structure.
Jakub
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for the reply.
I tried to put the pointer at the end of the structure, and it works of course.
The problem is that I should use the structure containing several pointers.
To the first pointer, it works properly, but it has wrong values after that.
Is there any other idea?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try following code
MODULE mod
TYPE test_t
INTEGER a
INTEGER b
INTEGER,POINTER::c(:)
integer d
INTEGER e
INTEGER f
INTEGER g
END TYPE
END MODULE mod
PROGRAM main
USE mod
IMPLICIT NONE
TYPE(test_t) input
integer*4 array(10)
pointer (parray,array)
input%a=1
input%b=2
input%d=5
input%e=6
input%f=7
input%g=8
parray=loc(input)
write(*,*) "size of input ",sizeof(input)
write(*,*) "values",array
ALLOCATE(input%c(2))
input%c(1)=3
input%c(2)=4
parray=loc(input) ! associate pointer
write(*,*) "size of input ",sizeof(input)
write(*,*) "values",array
write(*,*) "a address",loc(input.a)
write(*,*) "b address",loc(input.b)
write(*,*) "c address",loc(input.c)
write(*,*) "d address",loc(input.d)
write(*,*) "e address",loc(input.e)
END PROGRAM main
from addresses of members of structure (at the end of code) can be seen, that your structure is not in continuous block of memory (as is assumed by C code). You cannot use fortran pointers in structure if it is passed to C code
I modified member d to be integer to have the same type as array
Jakub
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try this code (it should work however I do not tested it).
MODULE mod
use ifwinty
TYPE test_t
INTEGER a
INTEGER b
integer(HANDLE) c
integer d
INTEGER e
INTEGER f
INTEGER g
END TYPE
END MODULE mod
PROGRAM main
USE mod
IMPLICIT NONE
TYPE(test_t) input
integer*4,allocatable :: c(:)
input%a=1
input%b=2
input%d=5
input%e=6
input%f=7
input%g=8
ALLOCATE(c(2))
c(1)=3
c(2)=4
input%c=loc(c) ! update pointer to data
call ...
END PROGRAM main
problem is that You should manage allocatable arrays separately of input structure and only update pointer to data input%c
Jakub
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
From the difference of adresses input.b amnd input.d (which should be 8 bytes - 4bytes of size a and 4bytes of size c) can be seen that FORTRAN adds another 32 bytes for pointer handling.
May be if you use your c structure like
typedef struct _test_t{
int a;
int b;
int* c;
int cpointerdummy[8]; // extra 8*4 bytes for FORTRAN pointer
float d;
int e;
int f;
int g;
} test_t;
your code should work as it was on the beginning
Jakub
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

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