I’m trying to modify 2D arrays using ccall, and this fails when the arrays contain complex double. The same code works when restricted to double.
MWE
Consider a C function which copies a 2D real array into a complex array.
#include <complex.h>
typedef double complex dcmplx; // like ComplexF64?
int sht(double** origin, dcmplx** target,
int array_size, int num_components) {
// copy origin elements to target for each component
for (int i=0;i<(int)(num_components);++i) {
for (int j=0;j<(int)(array_size);++j) {
(target[i])[j] = (origin[i])[j];
}
}
return 1;
}
I put this in a sht.c
file and compile it into sht.so
. Then I try to call it from Julia, following instructions from this possibly-out-of-date mailing list conversation.
# set up
origin = collect(1.0:3.0)
target = zeros(ComplexF64, 3)
pointer_origin = pointer([origin],1)
pointer_target = pointer([target],1)
# perform the call
ccall(
(:sht, "./sht.so"),
Cint,
(Ptr{Ptr{Cdouble}}, Ptr{Ptr{ComplexF64}}, Cint, Cint),
pointer_origin, pointer_target, 3, 1)
println(target) # want this to be [1.0, 2.0, 3.0]
This prints out the super weird
Array{Complex{Float64},1}[[]]
This same example appears to work when every dcmplx
and ComplexF64
is replaced with double
and Cdouble
.
Why is this happening? How can I achieve this functionality of being able to modify complex arrays in Julia using a C library?
Other Details
- Julia 1.3.1
- This MWE is based off of a problem I’ve encountered trying to assist in wrapping a C library that performs fast spherical harmonic transforms for Julia, hence the requirement for 2D arrays of complex numbers.
- The 2D arrays, i.e.
double**
, are very natural in this context, since depending on spin, a field on a sphere may be defined by more than one component. - I’ve put these two snippets into a repo if you want to try running them, with a simple makefile. There’s also a
main.c
in there to confirm that the C function works. - Sorry if this question has been answered before – I think there’s a fair number of past discussions, which helped me get this working for doubles. I’m not sure this has been discussed for complex doubles, though I don’t know why they’re different.