亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

用 Golang 和 C 編寫的 Python 模塊

用 Golang 和 C 編寫的 Python 模塊

Go
慕田峪9158850 2021-12-27 15:08:26
在 C 中編寫此代碼:#define Py_LIMITED_API#include <Python.h>PyObject * startVM(PyObject *, PyObject *);int PyArg_ParseTuple_S(PyObject * args, char* a) {      return PyArg_ParseTuple(args, "s", &a);}static PyMethodDef FooMethods[] = {      {"startVM", startVM, METH_VARARGS, "Starts."},    {NULL, NULL, 0, NULL}};static struct PyModuleDef foomodule = {     PyModuleDef_HEAD_INIT, "foo", NULL, -1, FooMethods};PyMODINIT_FUNC PyInit_foo(void) {    return PyModule_Create(&foomodule);}和這個代碼在 GO:package mainimport "fmt"// #cgo pkg-config: python3// #define Py_LIMITED_API// #include <Python.h>// int PyArg_ParseTuple_S(PyObject *,char *);import "C"//export startVMfunc startVM(self, args *C.PyObject) {      var a *C.char    if C.PyArg_ParseTuple_S(args, a) == 0 {        //return nil    }    fmt.Println(a)    //return C.PyBytes_FromString(&a)}func main() {}  我可以在 go 中編譯代碼,但是當我使用以下命令在 python 中調用模塊時python3 -c 'import foo; foo.startVM("hello")',它會打印 nil 并導致分段錯誤......有人知道如何修復它嗎?提前致謝。
查看完整描述

1 回答

?
哈士奇WWW

TA貢獻1799條經驗 獲得超6個贊

零輸出

這個功能:


int PyArg_ParseTuple_S(PyObject * args, char* a) {

    return PyArg_ParseTuple(args, "s", &a);

}

將只設置本地的副本a,并不會使其返回到調用函數,因為按值傳遞的字符串指針(復制),所以PyArg_ParseTuple只設置副本。


var a *C.char

C.PyArg_ParseTuple_S(args, a)

// Here `a` is not set, so it keeps its default value: nil.

您可以通過將指針傳遞給字符串而不是字符串本身來解決此問題:


// C

int PyArg_ParseTuple_S(PyObject * args, char** a) {

    return PyArg_ParseTuple(args, "s", a);

}


// Go

var a *C.char

if C.PyArg_ParseTuple_S(args, &a) == 0 {

    //return nil

}

正確印刷

fmt.Println(a)將打印 持有的地址a,而不是它指向的字符串。Go 有自己的字符串類型,不適用于 C 字符串。


如果要正確打印文本,則必須使用C.GoString以下命令對其進行轉換:


// C string to Go string

func C.GoString(*C.char) string

(來自https://golang.org/cmd/cgo/)


例如:


str := C.GoString(a)

fmt.Println(str)

分段故障。

我不熟悉 python 模塊開發,但我可以假設,錯誤發生了,因為 python 方法應該返回一個有效的PyObject*或NULL. 但是你的代碼沒有做這些。的返回值startVM沒有設置,也不是默認為nil,python接受這個非nil的指針作為一個有效的對象并解引用它,這會導致分段錯誤。


指定返回類型startVM可能會有所幫助:


//export startVM

func startVM(self, args *C.PyObject) *C.PyObject {  

    // ...some code...

    return nil

}


查看完整回答
反對 回復 2021-12-27
  • 1 回答
  • 0 關注
  • 215 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號