Instead of copying from a C uint32_t[] to a golang []uint32, we can exploit the fact that their underlying memory has the same representation. An unsafe cast to more memory than necessary exposes all the more that Go then needs to give a well-bounded slice, with no copying necessary. https://newbedev.com/pass-struct-and-array-of-structs-to-c-function-from-go --- generator/GoLang.ml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/generator/GoLang.ml b/generator/GoLang.ml index eb3aa26..7455dde 100644 --- a/generator/GoLang.ml +++ b/generator/GoLang.ml @@ -1,6 +1,6 @@ (* hey emacs, this is OCaml code: -*- tuareg -*- *) (* nbd client library in userspace: generator - * Copyright (C) 2013-2020 Red Hat Inc. + * Copyright (C) 2013-2021 Red Hat Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -513,13 +513,14 @@ import \"unsafe\" /* Closures. */ -func copy_uint32_array (entries *C.uint32_t, count C.size_t) []uint32 { - ret := make([]uint32, int (count)) - for i := 0; i < int (count); i++ { - entry := (*C.uint32_t) (unsafe.Pointer(uintptr(unsafe.Pointer(entries)) + (unsafe.Sizeof(*entries) * uintptr(i)))) - ret[i] = uint32 (*entry) - } - return ret +func use_uint32_array (entries *C.uint32_t, count C.size_t) []uint32 { + /* https://stackoverflow.com/questions/48756732/what-does-1-30c-yourtype-do-exa... */ + unsafePtr := unsafe.Pointer(entries) + /* Max structured reply payload is 64M, so this array size is more than + * sufficient for the underlying slice we want to expose. + */ + arrayPtr := (*[1 << 20]uint32)(unsafePtr) + return arrayPtr[:count:count] } "; @@ -601,7 +602,7 @@ func copy_uint32_array (entries *C.uint32_t, count C.size_t) []uint32 { if !comma then pr ", "; comma := true; match cbarg with | CBArrayAndLen (UInt32 n, count) -> - pr "copy_uint32_array (%s, %s)" n count + pr "use_uint32_array (%s, %s)" n count | CBBytesIn (n, len) -> pr "C.GoBytes (%s, C.int (%s))" n len | CBInt n -> -- 2.33.1