在 Julia 中声明 C 空指针的正确方法 [英] the proper way to declare C void pointers in Julia

查看:31
本文介绍了在 Julia 中声明 C 空指针的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我最初对这个问题的表述很糟糕(自从我认真编写 C++ 代码到现在已经一年多了,我对纯 C 的经验非常有限),所以让我们再试一次.

Ok, I originally badly screwed up my formulation of this question (it's more than a year now since I seriously wrote C++ code and I have pretty limited experience with pure C), so let's try again.

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

Some C code is written to expect you to do something like the following

void* p;
create_new_thing(&p);  //p is now a new thing
do_stuff_to_thing(p);  //something happened to p

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

My question is how to create the object p in Julia. Right now I believe the answer to be

p = Ref{Ptr{Void}}()
ccall((:create_new_thing, :lib), Void, (Ptr{Ptr{Void}},), p)
ccall((:do_stuff_to_thing, :lib), Void, (Ptr{Void},), p)

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

Furthermore, I believe the same code but with p declared instead as p = Array(Ptr{Void}, 1) also works.

然而,我确实发现 Julia 中 RefPtr 之间的整个区别非常令人困惑,主要是因为它们似乎以我无法跟踪的方式相互转换.

I do however find the whole distinction between Ref and Ptr in Julia very confusing, mostly because they seem to get converted between each other in ways I cannot keep track of.

推荐答案

您的代码看起来几乎没问题.不过要小心!任何小错误,例如您在此处遇到的错误,都可能导致分段错误:

Your code looks almost fine. But be careful! Any small error, like the one you have here, can cause a segmentation fault:

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  ^

正确的做法是

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  ^

了解在何处使用pp[] 的最简单方法是考虑相应的C 代码.在 C 中,我们写

The easiest way to understand where to use p and p[] is to think of the corresponding C code. In C, we write

void *p;
create_new_thing(&p)
do_stuff_to_thing(p)

Julia 对象不像 C 对象那样具有一流的内存地址,因此我们必须在 Julia 中使用 p = Ref{Ptr{Void}}() 来获取内存地址.这个对象,作为一个引用,在 C 中的行为类似于 &p.这意味着要获取对象本身,在 C 中,我们需要使用 p[] 在 Julia 中.

Julia objects do not have first-class memory addresses like C objects do, so we must use p = Ref{Ptr{Void}}() in Julia to get a memory address. This object, as a ref, behaves like &p in C. That means to get the object itself, p in C, we need to use p[] in Julia.

所以 Julia 中的等价物是

So the equivalent in Julia is

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

这篇关于在 Julia 中声明 C 空指针的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆