从Julia调用div C函数

时间:2014-07-21 16:26:46

标签: c julia

我正在尝试熟悉从Julia调用C函数。 我有一些像isalnum这样的简单函数的麻烦。

运行

ccall( (:isalnum, "libc"), Bool, (ASCIIString,), "k")

返回始终为false。

我也试过使用函数" div"返回分数的商和提醒。为了存储这两个值,我创建了一个类型

type Foo
         A::Int64
         B::Int64
end

然后运行

t = ccall( (:div, "libc"), Foo, (Int64,Int64,), 7,3)

但结果是错误的。

2 个答案:

答案 0 :(得分:1)

C函数 int isalnum(int c); 接受一个int并返回一个int。您可以将字符传递给 ccall ,它将自动转换为Int64,但函数 convert(:: Type {Int64},:: ASCIIString)不存在。

此外,C将任何非零视为真,将Julia从 Int 转换为 Bool 时也是如此,但当返回类型定义为 Bool时而不是 Int64 它不起作用。

julia> ccall((:isalnum,"libc"),Int64,(Int64,),'k') 
8

您可以将非整数作为参数传递,因为会隐式调用convert,但定义正确的返回类型很重要。

julia> convert(Bool,ccall((:isalnum,"libc"),Int64,(Int64,),'k'))
true

并通过比较

julia> convert(Bool,ccall((:isalnum,"libc"),Int64,(Int64,),' '))
false

答案 1 :(得分:1)

不幸的是,Julia目前不支持从ccalls返回结构。实现这一点的open pull request在0.3发布周期中落到了裂缝中并且没有合并。如果支持它(它将很快在主分支上),您将使用不可变结构使其工作。像这样:

julia> immutable Cdiv_t
           q::Cint
           r::Cint
       end

julia> ccall(:div, Cdiv_t, (Cint,Cint), 7, 3)
Cdiv_t(2,2)

正如您所看到的,这已被破坏,因为Cdiv_t结构的其余部分不正确(它当前将始终与商部分相同)。有必要使用不可变结构,因为可变结构需要将其组件作为单独分配的值存储在堆上 - 这与C结构布局不兼容。由于Cdiv_t是不可变的,因此它的组件可以内联存储,这就是C的作用。

另请注意使用Cint作为C int类型的Julia端镜像。这总是被定义,以便它是与C的int类型相对应的正确类型 - 这并不总是那么容易确定。调用C和Fortran的章节包含与C类型对应的a full list Julia类型。您通常希望在Julia代码中使用中间列名称,因为它们可以在任何地方使用,而不仅仅是在您的系统上。