Ben Bacarisse
3/23/2011 12:41:00 PM
Francogrex <franco@grex.org> writes:
> On Mar 23, 12:40Â pm, Mark Bluemel <mark_blue...@pobox.com>
>> what you are trying to achieve, preferably with some more meaningful
>> example code, and we may be able to help more.
>
> ok I don't know if you're prepared for this,
It's not that peculiar a situation.
> here is what I'm really
> trying to do. I have a fortran function that starts like this:
> FUNCTION AKSCDF (M,N,D,U)
> DIMENSION U(N)
> K = FLOAT (M * N) * D + 0.5
> U(1) = 1.0
> ... etc
> M, N are integers, D would be the equivalent of a float and U would be
> an array of floats
> The C wrapper around it that works correctly is this:
> void akscdf_(int*, int*, float *, float *);
> This is compiled to a dynamic library.
>
> Now the tricky part, there is an external application that accesses
> the dynamic library (so it accesses the fortran code through the c
> wrapper) but it can't send its arguments as int* or float*, it can
> only handle double*.
>
> Hence the reason I wanted to write a code on top
> of the C wrapper like this:
> Fix_akscdf_(double*, double*, double*, double*)
Do these first three have to be pointers? It will simplify matters if
the wrapper round the wrapper can be passed M, N and D directly. For
example, if Fix_akscdf_ is called only from C and AKSCDF does not alter
M, N or D you don't need the pointers.
> {
> akscdf_((double*)int*, (double*) int*, (double*)float*,
> (double*)float*)
> ...etc. Obviously the casting as done above is bad and I'm looking for
> a good way.
As it stands, you need to copy the values into variables of the right
type (which will do the conversion) and pass pointers to these copies.
You then need to copy the values back out for those variables that the
function might have changed.
The conversion could be done like this in C99:
void Fix_akscdf_(double *mp, double *np, double *dp, double *up)
{
int m = *mp, n = *np;
float d = *dp;
float u[n];
for (int i = 0; i < n; i++)
u[i] = up[i];
akscdf_(&m, &n, &d, u);
/* skip this if akscdf_ does not change the array */
for (int i = 0; i < n; i++)
up[i] = u[i];
/* skip this if akscdf_ does not change m, n or d */
*mp = m;
*np = n;
*dp = d;
}
If you can't use variably modified arrays (a C99 feature) you will need
to allocate the array using malloc and free it using free.
The cost of the copy might be quote high (how big is the array in a
typical call?) and so you might have to re-think this design. Maybe the
Fortran code an be re-written, maybe the calling code can be persuaded
to use a float array, and so on.
--
Ben.