Skip to content

Commit 40e2d59

Browse files
authored
Add unsafe_string for Cwstring (#36040)
Also adds some tests for Cwstring handling, fixes #28863.
1 parent 984749b commit 40e2d59

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

base/c.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,18 @@ function transcode(::Type{UInt8}, src::AbstractVector{UInt16})
414414
return dst
415415
end
416416

417+
function unsafe_string(p::Ptr{T}, length::Integer) where {T<:Union{UInt16,UInt32,Cwchar_t}}
418+
transcode(String, unsafe_wrap(Array, p, length; own=false))
419+
end
420+
function unsafe_string(cw::Cwstring)
421+
p = convert(Ptr{Cwchar_t}, cw)
422+
n = 1
423+
while unsafe_load(p, n) != 0
424+
n += 1
425+
end
426+
return unsafe_string(p, n - 1)
427+
end
428+
417429
# deferring (or un-deferring) ctrl-c handler for external C code that
418430
# is not interrupt safe (see also issue #2622). The sigatomic_begin/end
419431
# functions should always be called in matched pairs, ideally via:

test/ccall.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,3 +1686,18 @@ end
16861686
@ccall free(strp[]::Cstring)::Cvoid
16871687
@test str == "hi+1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-1.1-2.2-3.3-4.4-5.5-6.6-7.7-8.8-9.9\n"
16881688
end
1689+
1690+
@testset "Cwstring" begin
1691+
n = 100
1692+
buffer = Array{Cwchar_t}(undef, n)
1693+
if Sys.iswindows()
1694+
# sprintf throws an error on Windows, see https://github.com/JuliaLang/julia/pull/36040#issuecomment-634774055
1695+
len = @ccall swprintf_s(buffer::Ptr{Cwchar_t}, n::Csize_t, "α+%ls=%hhd"::Cwstring; "β"::Cwstring, 0xf::UInt8)::Cint
1696+
else
1697+
len = @ccall swprintf(buffer::Ptr{Cwchar_t}, n::Csize_t, "α+%ls=%hhd"::Cwstring; "β"::Cwstring, 0xf::UInt8)::Cint
1698+
end
1699+
str = GC.@preserve buffer unsafe_string(pointer(buffer), len)
1700+
@test str == "α+β=15"
1701+
str = GC.@preserve buffer unsafe_string(Cwstring(pointer(buffer)))
1702+
@test str == "α+β=15"
1703+
end

0 commit comments

Comments
 (0)