Re: [問題] 讓Python 用C運算 之 傳變數的問題

看板Python作者 (sbr)時間16年前 (2009/06/08 16:35), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串4/5 (看更多)
※ 引述《KSJ (阿真)》之銘言: : //下面這行本來是看看傳進下面funcB之前 這東西倒底有沒有問題的 : //return Py_BuildValue("N",pyFUNC_VARIABLEseqTuple); : //結果是 : //([1, 1, 2, 2], [1, 2, 1, 2], [5, 4, 6, 3], (8.72, 5.52), 0) : //所以我認定應該是沒問題 才繼續下面這一行 : PyObject *value = (*func)(NULL,pyFUNC_VARIABLEseqTuple); : 於是在這裡的最後一行 程式有誤 : 想必是進入funcB之後的問題?! : 於是我在funcB之中加入一些中斷點 來看看是哪裡的問題 : funcB只秀到有誤的部份: : //宣告要接的變數 有一個長整數 四個pyobejct : //長整數就是 最後的那個 0 四個pyobject就是 : //[1,1,2,2,] [1,2,1,2] [5,4,6,3] (8.72,5.52) 這四個 : long int func_num; : PyObject *pylagS,*pylagT,*pyCOV,*pyFitVar; : PySys_WriteStdout("parse OK");//中斷點1 : //傳遞參數 : if (!PyArg_ParseTuple(args, "(OOOOI)",\ : &pylagS,&pylagT,&pyCOV,&pyFitVar,&func_num)) return NULL; : PySys_WriteStdout("parse OK");//中斷點2 : 到中斷點1 印出parse OK 之後 : 程式就爆了…orz : 強調一下 如果單單只叫funcB (用手key值) 是沒問題的 我後來仔細看看你這一段描述,也對照過你提供的完整 source code,確定你在 描述時沒有筆誤。我想我應該找到問題點,但不確定這是否就是你欠缺的觀念。 首先 native function WMSE 一開始是如下 parse 傳進來的參數: if (!PyArg_ParseTuple(args, "(OOOOI)", &pylagS,&pylagT,&pyCOV,&pyFitVar,&func_num)) return NULL; 這表示 WMSE export 到 Python module 後被使用時預期 caller pass 單一個 tuple object,而此 tuple 依序裝著 4 個 object 與 1 個 int。 # in Python SEKSGUI.WMSE((a, b, c, e, 0)) 但是在 native function: PSO 中,程式準備好一個 tuple object(referenced by 'pyFUNC_VARIABLEseqTuple'),把這個 tuple 輸出到 standard output 是 ([1, 1, 2, 2], [1, 2, 1, 2], [5, 4, 6, 3], (8.72, 5.52), 0) 這個 tuple 也是依序持有 4 個 object 與 1 個 int object。 然而你不能把這個 tuple(address) 直接 pass 給 WMSE function,而必須要 把這個 tuple 裝進另一個 tuple(成為唯一的 element)後,再把 enclosing tuple pass 給 WMSE function,也就是說要 pass 如下的 object: (([1, 1, 2, 2], [1, 2, 1, 2], [5, 4, 6, 3], (8.72, 5.52), 0)) 以目前你的程式裡的做法: PyObject *value = (*func)(NULL,pyFUNC_VARIABLEseqTuple); 這相當於在 Python 端執行這樣的 statement: SEKSGUI.WMSE([1, 1, 2, 2], [1, 2, 1, 2], [5, 4, 6, 3], (8.72, 5.52), 0) pass 了五個參數而非 pass 一個 tuple 當作參數。 ------------------------------------------------------------------------- 以 C 語言來實作 Python function 時,native function 有以下形式的 prototype: static PyObject * function_name(PyObject *self, PyObject *args); static PyObject * function_name(PyObject *self, PyObject *args, PyObject *kw); 是分別對應到 Python 中的: def function_name(*args): ... def function_name(*args, **kw): ... 也就是說不管在 Python 端 pass 幾個參數給 native function,native function 都是收到一個 tuple(此 tuple 依序裝著 pass 過來的參數),反過來說 native function 的 formal parameter 'args' 收到一個 tuple 不代表 Python 端明白 pass 一個 tuple 當作 actua argument。 我認為當初你本來是打算把 WMSE 設計成如下使用: SEKSGUI.WMSE(aObj, bObj, cObj, dObj, aInt) 那麼 WMSE 在 parse 參數時使用 "OOOOI" 當作 format 即可。native function WMSE 的 formal parameter 'args' 會是收到一個 tuple: (aObj, bObj, cObj, dObj, aInt) -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 218.173.129.26 ※ 編輯: sbrhsieh 來自: 218.173.129.26 (06/08 16:45) ※ 編輯: sbrhsieh 來自: 218.173.129.26 (06/08 16:48)
文章代碼(AID): #1ABCq_5l (Python)
文章代碼(AID): #1ABCq_5l (Python)