Hi I am using a Fortran 90 code to call a C function. Since I am manipulating addresses, the arguments of the C function should be properly matched in Fortran. I am using ifort and icc to compile the code and working on 64 bit machine.
Some testing showed that this will work also with int32_t
, although to prevent eventual pitfalls, I would like to keep the uint32_t
The C functions I am calling has the following prototypes
uint32_t encode_(uint32_t x, uint32_t y)
uint32_t decode_(uint32_t dec)
I can't call these functions simply by doing something like
integer :: cod,encode
cod = encode(i,j)
This will produce gibberish. Therefore I am using a workaround:
void code2d_(uint32_t j[] ){
uint32_t i;
i=encode_(j[0],j[1]);
// the underscore is due to the FORTRAN naming convention
printf("Coded %10d \n",i);
}
And subsequently in Fortran
integer :: cod,code2d
cod = code2d(i,j)
Well obviously I have some problem with the mismatch of the argument types. Unfortunately I don't know how to fix this. Since in my decode/encode functions binary address arithmetic is done it is quite important to preserve the uint32_t
.
You could write a C function which takes a C_INT (or int in C) and then converts it to uint32_t. Then you link to this from Fortran.
in C:
in fortran:
Then you can use
integer_to_uint32_t_C
to pass Fortran integer values to C functions that expect theuint32_t
. Also, you might want to make a C function that converts in back to a plain oleint
so you can use the results in Fortran.You appear to know about iso_c_binding, as you use the tag. Study the Fortran 2003 interoperability with C. Read the tag description and some documentation like http://gcc.gnu.org/onlinedocs/gcc-4.9.0/gfortran/Interoperability-with-C.html . There is no place in modern Fortran for your trailing underscores and similar stuff.
Fortran doesn't have any unsigned types, you have to use the signed. As long as the signed values are positive, it works. If you need larger values, use larger integer type. You can
transfer()
the lower bytes to int32 if you need it.Third, Fortran uses some variants of pass by reference by default, especially for
bind(c)
procedures (it may be a reference to a copy or some other variant). You must use thevalue
attribute to pass by value.Recent versions of GCC are able to detect that we are mixing signed and unsigned types during link-time optimizations:
You can ignore the warning or disable it if you know what you are doing.