This doesn't work because the `x::Ref` field is a pointer to the Julia
object `x`, rather than a pointer to the data

(modifying your code to print x):

julia> ccall((:sum, "test"), Void, (Ref{Problem},), p)
n = 3, res = 0
x = 0x10d569d90
...

julia> unsafe_pointer_to_objref(convert(Ptr{Void}, 0x10d569d90))
Base.RefArray{Float64,Array{Float64,1},Void}([1.3,2.7,4.9],1,nothing)


The following works, but if you hold the pointer or call back in to a Julia
`cfunction` during the ccall, make sure that x is not garbage collected
(for example, by holding a reference to it in a global array).

type Problem
           n::Cint
           x::Ptr{Cdouble}
           res::Cdouble
end

...

p = Problem(length(x), pointer(x), 0.)


On Mon, Jan 4, 2016 at 6:07 AM, Andre Manoel <[email protected]> wrote:

> Hi,
>
> I'm trying to call the following C function from Julia using ccall
>
> void sum(Problem *P) {
>     int i;
>     printf("n = %d, res = %g\n", P->n, P->res);
>     for (i = 0; i < P->n; i++) {
>         P->res += P->x[i];
>         printf("x[i] = %g, res = %g\n", P->x[i], P->res);
>     }
> }
>
> which takes as argument the following struct
>
> typedef struct Problem {
>     int n;
>     double *x;
>     double res;
> } Problem;
>
> My Julia code is
>
> type Problem
>     n::Cint
>     x::Ref{Cdouble}
>     res::Cdouble
> end
>
> x = [1.3, 2.7, 4.9]
> p = Problem(length(x), x, 0.)
> ccall((:sum, "test"), Void, (Ref{Problem},), p)
> println(p.res)
>
> While I can read the n and res variables from inside the C function, I
> can't read the x array. According to
> http://docs.julialang.org/en/release-0.4/manual/calling-c-and-fortran-code/,
> "arrays of unknown size are not supported.". Is that the case here? Does
> anyone know if it would be too hard to lift this restriction?
>
> Thanks,
> Andre
>

Reply via email to