如何调用修改go内存的C函数?
admin 阅读:145 2024-03-18

假设我有一个带签名的 C 函数
// myclib.h void modify(double* ptr, int N);
这会改变参数指针 ptr 指向的内存。
以下代码对于 Go 的垃圾收集器来说是否安全?是否需要 runtimer.Pinner?
package main
// #cgo CFLAGS: -g -Wall
// #include "myclib.h"
import "C"
import (
"fmt"
"runtime"
)
func modifyWrapper(v []float64) {
ptr := (*C.double)(&v[0])
N := (C.int)(len(v))
pinner := runtime.Pinner{}
pinner.Pin(ptr)
C.modify(ptr, N)
pinner.Unpin()
}
func main() {
v := []float64{9.0, 2.0, 1.0, 4.0, 5.0}
modifyWrapper(v)
}
正确答案
package main
/*
#cgo CFLAGS: -g -Wall
#include <stdio.h>
void modify(double* ptr, int N) {
if (!ptr || N <= 0) {
return;
}
printf("modify: %g %dn", *ptr, N);
*ptr = 42;
printf("modify: %g %dn", *ptr, N);
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func modify(v []float64) {
ptr := (*C.double)(unsafe.SliceData(v))
N := (C.int)(len(v))
C.modify(ptr, N)
}
func main() {
v := []float64{9.0, 2.0, 1.0, 4.0, 5.0}
fmt.Println(v)
modify(v)
fmt.Println(v)
}[9 2 1 4 5] modify: 9 5 modify: 42 5 [42 2 1 4 5]
声明
1、部分文章来源于网络,仅作为参考。 2、如果网站中图片和文字侵犯了您的版权,请联系1943759704@qq.com处理!



