在Julia中声明C void指针的正确方法

Exp*_*Man 9 c void-pointers julia

好吧,我最初严重搞砸了我对这个问题的描述(自从我认真编写C++代码以来我已经超过一年了,我对纯C的经验非常有限),让我们再试一次.

编写一些C代码以期望您执行以下操作

void* p;
create_new_thing(&p);  //p is now a new thing
do_stuff_to_thing(p);  //something happened to p
Run Code Online (Sandbox Code Playgroud)

我的问题是如何p在Julia中创建对象.现在我相信答案

p = Ref{Ptr{Void}}()
ccall((:create_new_thing, :lib), Void, (Ptr{Ptr{Void}},), p)
ccall((:do_stuff_to_thing, :lib), Void, (Ptr{Void},), p)
Run Code Online (Sandbox Code Playgroud)

此外,我相信相同的代码,但p声明相反p = Array(Ptr{Void}, 1)也有效.

然而,我发现整个之间的区别Ref,并Ptr在朱莉娅非常混乱,主要是因为他们似乎的方式,我不能跟踪相互之间进行转换得到.

Fen*_*ang 10

你的代码看起来几乎罚款.不过要小心!任何小错误,如您在这里的错误,都可能导致分段错误:

p = Ref{Ptr{Void}}()
ccall((:create_new_thing, :lib), Void, (Ptr{Ptr{Void}},), p)
ccall((:do_stuff_to_thing, :lib), Void, (Ptr{Void},), p)
                                        # error here  ^
Run Code Online (Sandbox Code Playgroud)

正确的方法是

p = Ref{Ptr{Void}}()
ccall((:create_new_thing, :lib), Void, (Ptr{Ptr{Void}},), p)
ccall((:do_stuff_to_thing, :lib), Void, (Ptr{Void},), p[])
                                             # fixed  ^
Run Code Online (Sandbox Code Playgroud)

最简单的方法来了解在哪里使用p,并p[]是考虑相应的C代码.在C中,我们写

void *p;
create_new_thing(&p)
do_stuff_to_thing(p)
Run Code Online (Sandbox Code Playgroud)

Julia对象没有像C对象那样的第一类内存地址,所以我们必须p = Ref{Ptr{Void}}()在Julia中使用来获取内存地址.这个对象,作为ref,就像&p在C中一样.这意味着在C中获取对象本身p,我们需要p[]在Julia中使用.

所以朱莉娅的等价物是

p = Ref{Ptr{Void}}()                 # this p corresponds to &p in C
ccall(:create_new_thing, ..., p)     # like &p
ccall(:do_stuff_to_thing, ..., p[])  # like *(&p); that is, like p
Run Code Online (Sandbox Code Playgroud)