typedef struct __kstring_t {
size_t l, m;
char *s;
} kstring_t;
kstring_t * get_ptr_of_kstr(int num){
char * ch = (char *)malloc(num);
kstring_t kstr = {0, num, ch};
kstring_t *p = &kstr;
printf("In C, kstr.l: %zu\n", p->l);
printf("In C, kstr.m: %zu\n", p->m);
printf("In C, kstr.s: %p\n", p->s);
printf("In C, pointer to kstr: %p\n", p);
return p;
};
type KStr
l::Csize_t
m::Csize_t
s::Ptr{Cchar}
end
When I use ccall to call get_ptr_of_kstr and get a pointer of kstring_t in Julia, use unsafe_load to get its value, but the value seems wrong.
The messages are below:
In C, kstr.l: 0
In C, kstr.m: 100000
In C, kstr.s: 0x37b59b0
In C, pointer to kstr: 0x7fffe7d80b90
kstr = Ptr{HT.KStr} @0x00007fffe7d80b90
unsafe_load(kstr).s = Ptr{Int8} @0x00007fffe7d80b90
The value of unsafe_load(kstr).s is same as kstr. Why? how to fix it?
Regarding the C part (I don't know the bindings between Julia and C):
kstring_t kstr = {0, num, ch};
That would allocate kstr on the stack in the get_ptr_of_kstr() context. And the pointer to it you return is invalid right after the function exits. You can't use anymore after that, not in C or any other program you might pass it to.
As @LutfullahTomak hinted, you should either:
malloc()/calloc(),static in the body of the function, which makes it a global variable which scope is reduced to the function only. Note that it is not good practice though.Also, note that your C compiler will align each struct member to an address, depending on its options and #pragma pack (if used), so the offset of each field might not be what you or Julia expects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With