我试图了解在
cgo
中使用 CString 和
golang
时如何正确释放内存
这是我想要制作的工作代码“内存安全”:
basic.go
:
package main
// #include <stdlib.h>
import "C"
import (
"github.com/pemistahl/lingua-go"
)
var lan lingua.Language
//export Langdetectfunct
func Langdetectfunct(text *C.char) int {
textS := C.GoString(text);
detector := lingua.NewLanguageDetectorBuilder().
FromAllLanguages().
Build()
language, _ := detector.DetectLanguageOf(textS)
return int(language)
}
func main() {}
basic1.cpp
:
#include "basic.h"
int main() {
auto text = "It is a beautiful day, today";
int res = Langdetectfunct(const_cast<char *>(text));
std::cout << "res: " << res << std::endl;
}
使用
c-shared
buildmode 构建 basic.go 后:
raphy@raohy:~/go-lang-detect$ go build -o basic.so -buildmode=c-shared basic.go
并使用
basic.so
: 编译 basic1.cpp
raphy@raohy:~/go-lang-detect$ g++ -o basic basic1.cpp ./basic.so
我得到了正确的输出:
raphy@raohy:~/go-lang-detect$ ./basic
res: 17
那很好...
但是:如何使代码“内存安全”?
我尝试过这样的方式:
basic.go
:
package main
// #include <stdlib.h>
import "C"
import "unsafe"
import (
"github.com/pemistahl/lingua-go"
)
var lan lingua.Language
//export Langdetectfunct
func Langdetectfunct(text *C.char) int {
textS := C.GoString(text);
detector := lingua.NewLanguageDetectorBuilder().
FromAllLanguages().
Build()
language, _ := detector.DetectLanguageOf(textS)
return int(language)
C.free(unsafe.Pointer(text))
}
func main() {}
但是,当构建时,我得到了,可以理解的是,这个错误:
raphy@raohy:~/go-lang-detect$ go build -o basic.so -buildmode=c-shared basic.go
./basic.go:39:1: missing return
如果我将
C.free(unsafe.Pointer(text))
放在 return 语句之前:
package main
// #include <stdlib.h>
import "C"
import "unsafe"
import (
"github.com/pemistahl/lingua-go"
)
var lan lingua.Language
//export Langdetectfunct
func Langdetectfunct(text *C.char) int {
textS := C.GoString(text);
detector := lingua.NewLanguageDetectorBuilder().
FromAllLanguages().
Build()
language, _ := detector.DetectLanguageOf(textS)
C.free(unsafe.Pointer(text))
return int(language)
}
func main() {}
运行可执行文件时,出现:
free(): invalid pointer
错误:
raphy@raohy:~/go-lang-detect$ go build -o basic.so -buildmode=c-shared basic.go
raphy@raohy:~/go-lang-detect$ g++ -o basic basic1.cpp ./basic.so
raphy@raohy:~/go-lang-detect$ ./basic
free(): invalid pointer
Aborted (core dumped)
auto text =“今天是美好的一天”;
text
位于堆栈位置。你无法释放它。