forked from JuliaLang/julia
-
Notifications
You must be signed in to change notification settings - Fork 0
/
c.jl
119 lines (102 loc) · 3.89 KB
/
c.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# This file is a part of Julia. License is MIT: http:https://julialang.org/license
# definitions related to C interface
import Core.Intrinsics: cglobal, box, unbox
cfunction(f::Function, r, a) = ccall(:jl_function_ptr, Ptr{Void}, (Any, Any, Any), f, r, a)
if ccall(:jl_is_char_signed, Any, ())
typealias Cchar Int8
else
typealias Cchar UInt8
end
typealias Cuchar UInt8
typealias Cshort Int16
typealias Cushort UInt16
typealias Cint Int32
typealias Cuint UInt32
if OS_NAME === :Windows
typealias Clong Int32
typealias Culong UInt32
typealias Cwchar_t UInt16
else
typealias Clong Int
typealias Culong UInt
typealias Cwchar_t Int32
end
typealias Cptrdiff_t Int
typealias Csize_t UInt
typealias Cssize_t Int
typealias Cintmax_t Int64
typealias Cuintmax_t UInt64
typealias Clonglong Int64
typealias Culonglong UInt64
typealias Cfloat Float32
typealias Cdouble Float64
const sizeof_off_t = ccall(:jl_sizeof_off_t, Cint, ())
if sizeof_off_t === 4
typealias FileOffset Int32
else
typealias FileOffset Int64
end
typealias Coff_t FileOffset
# C NUL-terminated string pointers; these can be used in ccall
# instead of Ptr{Cchar} and Ptr{Cwchar_t}, respectively, to enforce
# a check for embedded NUL chars in the string (to avoid silent truncation).
if Int === Int64
bitstype 64 Cstring
bitstype 64 Cwstring
else
bitstype 32 Cstring
bitstype 32 Cwstring
end
convert{T<:Union(Int8,UInt8)}(::Type{Cstring}, p::Ptr{T}) = box(Cstring, unbox(Ptr{T}, p))
convert(::Type{Cwstring}, p::Ptr{Cwchar_t}) = box(Cwstring, unbox(Ptr{Cwchar_t}, p))
# convert strings to ByteString etc. to pass as pointers
cconvert(::Type{Cstring}, s::AbstractString) = bytestring(s)
cconvert(::Type{Cwstring}, s::AbstractString) = wstring(s)
containsnul(p::Ptr, len) = C_NULL != ccall(:memchr, Ptr{Cchar}, (Ptr{Cchar}, Cint, Csize_t), p, 0, len)
function unsafe_convert(::Type{Cstring}, s::ByteString)
p = unsafe_convert(Ptr{Cchar}, s)
if containsnul(p, sizeof(s))
throw(ArgumentError("embedded NUL chars are not allowed in C strings"))
end
return Cstring(p)
end
# symbols are guaranteed not to contain embedded NUL
convert(::Type{Cstring}, s::Symbol) = Cstring(unsafe_convert(Ptr{Cchar}, s))
# in string.jl: unsafe_convert(::Type{Cwstring}, s::WString)
# deferring (or un-deferring) ctrl-c handler for external C code that
# is not interrupt safe (see also issue #2622). The sigatomic_begin/end
# functions should always be called in matched pairs, ideally via:
# disable_sigint() do .. end
# reennable_sigint is provided so that immediate ctrl-c handling is
# re-enabled within a sigatomic region, e.g. inside a Julia callback function
# within a long-running C routine.
sigatomic_begin() = ccall(:jl_sigatomic_begin, Void, ())
sigatomic_end() = ccall(:jl_sigatomic_end, Void, ())
disable_sigint(f::Function) = try sigatomic_begin(); f(); finally sigatomic_end(); end
reenable_sigint(f::Function) = try sigatomic_end(); f(); finally sigatomic_begin(); end
function ccallable(f::Function, rt::Type, argt::Type, name::Union(AbstractString,Symbol)=string(f))
ccall(:jl_extern_c, Void, (Any, Any, Any, Cstring), f, rt, argt, name)
end
function ccallable(f::Function, argt::Type, name::Union(AbstractString,Symbol)=string(f))
ccall(:jl_extern_c, Void, (Any, Ptr{Void}, Any, Cstring), f, C_NULL, argt, name)
end
macro ccallable(def)
if isa(def,Expr) && (def.head === :(=) || def.head === :function)
sig = def.args[1]
if sig.head === :call
name = sig.args[1]
at = map(sig.args[2:end]) do a
if isa(a,Expr) && a.head === :(::)
a.args[2]
else
:Any
end
end
return quote
$(esc(def))
ccallable($(esc(name)), $(Expr(:tuple, map(esc, at)...)))
end
end
end
error("expected method definition in @ccallable")
end