As the title suggests, I’ve run into very puzzling behavior with Cxx and unsafe_wrap(). I’ve got some c++ code that returns vector<vector<uint8_t>>&
which I’m viewing in Julia. I can perform the same operation twice in a row and get different answers each time. I’ve put together a code snippet that demonstrates the behavior I’m seeing:
using Cxx cxx""" #include <vector> struct vholder { std::vector<std::vector<uint8_t>> data; vholder() { std::vector<float> f1{1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1}; std::vector<uint8_t> c1(8*sizeof(float)); std::memcpy(c1.data(), f1.data(), 8*sizeof(float)); data.push_back(c1); std::vector<float> f2{2.2, 2.2, 2.2, 2.2, 2.2, 2.2, 2.2, 2.2}; std::vector<uint8_t> c2(8*sizeof(float)); std::memcpy(c2.data(), f2.data(), 8*sizeof(float)); data.push_back(c2); std::vector<float> f3{3.3, 3.3, 3.3, 3.3, 3.3, 3.3, 3.3, 3.3}; std::vector<uint8_t> c3(8*sizeof(float)); std::memcpy(c3.data(), f3.data(), 8*sizeof(float)); data.push_back(c3); std::vector<float> f4{4.4, 4.4, 4.4, 4.4, 4.4, 4.4, 4.4, 4.4}; std::vector<uint8_t> c4(8*sizeof(float)); std::memcpy(c4.data(), f4.data(), 8*sizeof(float)); data.push_back(c4); } std::vector<std::vector<uint8_t>>& get_data() { return data; } }; """ vholder = @cxxnew vholder() vdata = @cxx vholder->get_data() jdata = [reinterpret(Complex{Float32}, unsafe_wrap(Array, pointer(v), length(v))) for v in vdata] display(jdata) jdata = [reinterpret(Complex{Float32}, unsafe_wrap(Array, pointer(v), length(v))) for v in vdata] display(jdata)
I’ve written the C++ part to make it very obvious what the expected result should be after Julia has done its part. When I run the code, this is what I see:
4-element Array{Base.ReinterpretArray{Complex{Float32},1,UInt8,Array{UInt8,1}},1}: [4.048057f-36 + 0.0f0im, 4.047994f-36 + 0.0f0im, 7.0f-45 + 1.0f-42im, 3.0f-45 + 0.0f0im] [1.7337694f-38 + 0.0f0im, 0.0f0 + 0.0f0im, 1.8f-44 + 0.0f0im, 2.0056614f-36 + 0.0f0im] [1.7337694f-38 + 0.0f0im, 0.0f0 + 0.0f0im, 1.8f-44 + 0.0f0im, 4.664f-42 + 0.0f0im] [6.0541977f-37 + 0.0f0im, 3.1095097f-36 + 0.0f0im, 7.0f-45 + 4.9f-44im, 3.0f-45 + 0.0f0im] 4-element Array{Base.ReinterpretArray{Complex{Float32},1,UInt8,Array{UInt8,1}},1}: [1.1f0 + 1.1f0im, 1.1f0 + 1.1f0im, 1.1f0 + 1.1f0im, 1.1f0 + 1.1f0im] [2.2f0 + 2.2f0im, 2.2f0 + 2.2f0im, 2.2f0 + 2.2f0im, 2.2f0 + 2.2f0im] [3.3f0 + 3.3f0im, 3.3f0 + 3.3f0im, 3.3f0 + 3.3f0im, 3.3f0 + 3.3f0im] [4.4f0 + 4.4f0im, 4.4f0 + 4.4f0im, 4.4f0 + 4.4f0im, 4.4f0 + 4.4f0im]
I set the c++ code up specifically with the intention of making the lifetime of the object returned longer than Julia’s need to examine it, but may have failed at this.