问题内容
我试图将二维数组从 Go 传递到某个 C 函数 void foo(in **float, out *double)
。因为我想要这个 C 函数的包装器,所以我希望 Go 函数具有像 func FooWrapper([][]float32) []float64
这样的定义。最简单但效率不高的实现是通过下面列出的 C 来分配所有内存:
<code>func FooWrapper(values [][]float32) []float64 { totalObj := len(values) totalParams := len(values[0]) results := make([]float64, totalObj) ptrArrLength := uintptr(totalObj) * cPointerSize paramArrLength := uintptr(totalParams) * cFloatSize ptr := C.malloc(C.size_t(ptrArrLength + paramArrLength*uintptr(totalObj))) defer C.free(ptr) ptrSlice := unsafe.Slice((**C.float)(ptr), totalObj) for i, obj := range values { paramArrPtr := (*C.float)(unsafe.Add(ptr, ptrArrLength+uintptr(i)*paramArrLength)) ptrSlice[i] = paramArrPtr paramSlice := unsafe.Slice(paramArrPtr, totalParams) for j, param := range obj { paramSlice[j] = (C.float)(param) } } C.foo((**C.float)(ptr), (*C.double)(&results[0])) return results } </code>
这样的实施安全吗?我可以传递result
数据的指针吗?据我所知,这个指针将被固定,因为它传递给了 C 函数。
但是我想分配更少的内存,只是重用Go内存,我已经了解了 runtime.Pinner
,它使指针固定直到 runtime.Pinner.Unpin()
调用。我尝试使用 pinner 编写另一个实现:
<code>func FooWrapper(values [][]float32) []float64 { length := len(values) results := make([]float64, length) pinner := runtime.Pinner{} defer pinner.Unpin() arr := (**C.float)(C.malloc(C.size_t(uintptr(length) * cPointerSize))) defer C.free(unsafe.Pointer(arr)) slice := unsafe.Slice(arr, length) for i, v := range values { pinner.Pin(&v[0]) slice[i] = (*C.float)(&v[0]) } C.foo(arr, (*C.double)(&results[0])) return results } </code>
但是,不幸的是,这段代码不起作用
runtime: pointer 0xc016ecbfc0 to unused region of span span.base()=0xc016eca000 span.limit=0xc016ecbfa0 span.state=1 fatal error: found bad pointer in Go heap (incorrect use of unsafe or cgo?)
我使用runtime.Pinner是否错误(据我所知,我可以固定切片数据)?或者这段代码还有另一个错误。除了将所有数据分配和复制到 C 内存之外,是否有一些将 3d(4d 等)数组传递给 C 函数的实现?
解决方法
我找到了问题的答案。使用 malloc 是危险的,因为当我尝试将 Go 指针写入 C 内存时,GC 可以将未初始化的内存识别为“坏”内存,因此如果我将 malloc 更改为 calloc 就不会出现问题。当然这不是最好的解决方案,最好在 Go 中分配内存,因为它更快、更安全。
所有讨论此处一个>.
以上是使用runtime.Pinner将二维数组从Go传递到C的详细内容。更多信息请关注PHP中文网其他相关文章!

C 更适合需要直接控制硬件资源和高性能优化的场景,而Golang更适合需要快速开发和高并发处理的场景。1.C 的优势在于其接近硬件的特性和高度的优化能力,适合游戏开发等高性能需求。2.Golang的优势在于其简洁的语法和天然的并发支持,适合高并发服务开发。

Golang在实际应用中表现出色,以简洁、高效和并发性着称。 1)通过Goroutines和Channels实现并发编程,2)利用接口和多态编写灵活代码,3)使用net/http包简化网络编程,4)构建高效并发爬虫,5)通过工具和最佳实践进行调试和优化。

Go语言的核心特性包括垃圾回收、静态链接和并发支持。1.Go语言的并发模型通过goroutine和channel实现高效并发编程。2.接口和多态性通过实现接口方法,使得不同类型可以统一处理。3.基本用法展示了函数定义和调用的高效性。4.高级用法中,切片提供了动态调整大小的强大功能。5.常见错误如竞态条件可以通过gotest-race检测并解决。6.性能优化通过sync.Pool重用对象,减少垃圾回收压力。

Go语言在构建高效且可扩展的系统中表现出色,其优势包括:1.高性能:编译成机器码,运行速度快;2.并发编程:通过goroutines和channels简化多任务处理;3.简洁性:语法简洁,降低学习和维护成本;4.跨平台:支持跨平台编译,方便部署。

关于SQL查询结果排序的疑惑学习SQL的过程中,常常会遇到一些令人困惑的问题。最近,笔者在阅读《MICK-SQL基础�...

golang ...

Go语言中如何对比并处理三个结构体在Go语言编程中,有时需要对比两个结构体的差异,并将这些差异应用到第�...


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

禅工作室 13.0.1
功能强大的PHP集成开发环境

SublimeText3 Linux新版
SublimeText3 Linux最新版

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

记事本++7.3.1
好用且免费的代码编辑器

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。