php小編西瓜在這里為大家分享關于Go語言中處理返回CString時的內存泄漏問題的解決方法。在Go語言中,C字符串是以null結尾的字節數組,而Go語言的字符串是以長度為前綴的字節數組。當我們需要將Go字符串轉換為C字符串并返回時,需要注意內存的分配和釋放,以避免內存泄漏問題的發生。本文將介紹幾種處理內存泄漏的方法,幫助大家解決這個常見的問題。
問題內容
我有以下函數簽名,然后返回 json 字符串
func getdata(symbol, day, month, year *c.char) *c.char {
combine, _ := json.marshal(combinerecords)
log.println(string(combine))
return c.cstring(string(combine))
}
登錄后復制
然后在 python 中調用 go 代碼
import ctypes
from time import sleep
library = ctypes.cdll.LoadLibrary('./deribit.so')
get_data = library.getData
# Make python convert its values to C representation.
# get_data.argtypes = [ctypes.c_char_p, ctypes.c_char_p,ctypes.c_char_p,ctypes.c_char_p]
get_data.restype = ctypes.c_char_p
for i in range(1,100):
j= get_data("BTC".encode("utf-8"), "5".encode("utf-8"), "JAN".encode("utf-8"), "23".encode("utf-8"))
# j= get_data(b"BTC", b"3", b"JAN", b"23")
print('prnting in Python')
# print(j)
sleep(1)
登錄后復制
它在 python 端工作得很好,但我擔心當在 python 端循環調用該函數時會出現內存泄漏。
如何處理內存泄漏?我應該返回 bytes 而不是 cstring 并在 python 端處理字節以避免內存泄漏嗎?我確實找到了這個鏈接來處理它,但不知何故我不知道編組后返回的 json 字符串的大小
解決方法
python 應該如下所示:
import ctypes
from time import sleep
library = ctypes.cdll('./stackoverflow.so')
get_data = library.getdata
free_me = library.freeme
free_me.argtypes = [ctypes.pointer(ctypes.c_char)]
get_data.restype = ctypes.pointer(ctypes.c_char)
for i in range(1,100):
j = get_data("", "", "")
print(ctypes.c_char_p.from_buffer(j).value)
free_me(j)
sleep(1)
登錄后復制
go 應該是這樣的:
package main
/*
#include
*/
import "c"
import (
"log"
"unsafe"
)
//export getdata
func getdata(symbol, day, month, year *c.char) *c.char {
combine := "combine"
log.println(string(combine))
return c.cstring(string(combine))
}
//export freeme
func freeme(data *c.char) {
c.free(unsafe.pointer(data))
}
func main() {}
登錄后復制
并使用此命令行生成共享庫:
python3 --version python 3.8.10 go version go version go1.19.2 linux/amd64 go build -o stackoverflow.so -buildmode=c-shared github.com/sjeandeaux/stackoverflow python3 stackoverflow.py 2023/01/03 13:54:14 combine b'combine' ...
登錄后復制
from ubuntu:18.04 run apt-get update -y && apt-get install python -y copy stackoverflow.so stackoverflow.so copy stackoverflow.py stackoverflow.py cmd ["python", "stackoverflow.py"]
登錄后復制
docker build --tag stackoverflow . docker run -ti stackoverflow 2023/01/03 15:04:24 combine b'combine' ...
登錄后復制






