Skip to content

Instantly share code, notes, and snippets.

@vrzh
Created April 15, 2021 08:06
Show Gist options
  • Save vrzh/e338c886931503214e78b96aa0bd7c72 to your computer and use it in GitHub Desktop.
Save vrzh/e338c886931503214e78b96aa0bd7c72 to your computer and use it in GitHub Desktop.
Modifying Tuples with Julia ccall
using CEnum
const mytype = NTuple{3, Cdouble}
struct mystruct
x::mytype
y::Ptr{mytype}
n::Cint
end
function get()
ccall((:get, libtest), Ptr{mystruct}, ())
end
function f(a)
# ccall((:f, libtest), Cvoid, (mytype,), a) # as generated by default (does not work)
ccall((:f, libtest), Cvoid, (Ptr{mytype},), a) # manually changed (works)
end
const N = 3
#include <stdio.h>
#include <stdlib.h>
#include "test.h"
// arbitrary code
mystruct * get(void){
mystruct * r = malloc(sizeof(mystruct));
for(int j = 0; j < N; j++){
r->x[j] = 1;
}
int n = 5;
r->y = malloc(n * sizeof(mystruct));
for(int i = 0; i < n; i++){
for(int j = 0; j < N; j++){
r->y[i][j] = i + 1;
}
}
r->n = n;
return r;
}
// arbitrary code to modify a `mytype`
void f(mytype a){
for(int j = 0; j < N; j++){
a[j] = -a[j];
}
}
#define N 3
typedef double mytype[N]; // no control over this typedef
typedef struct { // no control over this typedef
mytype x;
mytype * y;
int n;
} mystruct;
mystruct * get(void); // retrieve mystruct object
void f(mytype a); // modify mytype object
include("LibTest.jl")
const libtest = "./libtest.so"
qp = get()
q = unsafe_load(qp)
function myprint()
println("x = ", q.x[1])
for i = 1:q.n
println("y = ", unsafe_load(q.y, i))
end
end
myprint()
f(Ptr{mytype}(qp)) # making a change to `x` member
for i = 1:q.n
f(q.y + (i - 1) * sizeof(mytype))
end
q = unsafe_load(qp) # have to reload for changes in x member
myprint()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment