mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-04 19:17:47 +00:00
cgo: add support for C.CString and related functions
This commit is contained in:
committed by
Ron Evans
parent
6bd18af5ef
commit
c31aef06ba
@@ -42,6 +42,9 @@ func memzero(ptr unsafe.Pointer, size uintptr)
|
||||
//export strlen
|
||||
func strlen(ptr unsafe.Pointer) uintptr
|
||||
|
||||
//export malloc
|
||||
func malloc(size uintptr) unsafe.Pointer
|
||||
|
||||
// Compare two same-size buffers for equality.
|
||||
func memequal(x, y unsafe.Pointer, n uintptr) bool {
|
||||
for i := uintptr(0); i < n; i++ {
|
||||
|
||||
@@ -13,9 +13,6 @@ func libc_write(fd int32, buf unsafe.Pointer, count uint) int
|
||||
//export usleep
|
||||
func usleep(usec uint) int
|
||||
|
||||
//export malloc
|
||||
func malloc(size uintptr) unsafe.Pointer
|
||||
|
||||
// void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
|
||||
// Note: off_t is defined as int64 because:
|
||||
// - musl (used on Linux) always defines it as int64
|
||||
|
||||
@@ -233,3 +233,50 @@ func isContinuation(b byte) bool {
|
||||
// Continuation bytes have their topmost bits set to 0b10.
|
||||
return b&0xc0 == 0x80
|
||||
}
|
||||
|
||||
// Functions used in CGo.
|
||||
|
||||
// Convert a Go string to a C string.
|
||||
func cgo_CString(s _string) unsafe.Pointer {
|
||||
buf := malloc(s.length + 1)
|
||||
memcpy(buf, unsafe.Pointer(s.ptr), s.length)
|
||||
*(*byte)(unsafe.Pointer(uintptr(buf) + s.length)) = 0 // trailing 0 byte
|
||||
return buf
|
||||
}
|
||||
|
||||
// Convert a C string to a Go string.
|
||||
func cgo_GoString(cstr unsafe.Pointer) _string {
|
||||
if cstr == nil {
|
||||
return _string{}
|
||||
}
|
||||
return makeGoString(cstr, strlen(cstr))
|
||||
}
|
||||
|
||||
// Convert a C data buffer to a Go string (that possibly contains 0 bytes).
|
||||
func cgo_GoStringN(cstr unsafe.Pointer, length uintptr) _string {
|
||||
return makeGoString(cstr, length)
|
||||
}
|
||||
|
||||
// Make a Go string given a source buffer and a length.
|
||||
func makeGoString(cstr unsafe.Pointer, length uintptr) _string {
|
||||
s := _string{
|
||||
length: length,
|
||||
}
|
||||
if s.length != 0 {
|
||||
buf := make([]byte, s.length)
|
||||
s.ptr = &buf[0]
|
||||
memcpy(unsafe.Pointer(s.ptr), cstr, s.length)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Convert a C data buffer to a Go byte slice.
|
||||
func cgo_GoBytes(ptr unsafe.Pointer, length uintptr) []byte {
|
||||
// Note: don't return nil if length is 0, to match the behavior of C.GoBytes
|
||||
// of upstream Go.
|
||||
buf := make([]byte, length)
|
||||
if length != 0 {
|
||||
memcpy(unsafe.Pointer(&buf[0]), ptr, uintptr(length))
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user