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
>