Re: [問題] 讓Python 用C運算 之 傳變數的問題
感謝回應
看完之後
這的確是我不知道的觀念…
整理一下心得
原來函式可以這樣寫:
SEKSGUI.WMSE(aObj, bObj, cObj, dObj, aInt)
我一直以為只能 函數(一個變數)
還想說怎麼傳變數的方式那麼不人性...orz
幸好有tuple list這些東西 可以讓我把需要的變數包一包 再分裝就好
原來...程式自己會幫忙包好
也就是說...我自己又多包了一層orz...
這問題在python與c之間傳 是看不出來的
因為在 parse函式中 的 ("()",…) 就把我自行包好的消掉了
但作法是多此一舉orz...
但直接在c下使用時 等於是跳過了程式幫忙包裝
解決辨法是
1.對我來說其實根本不用包 至少我的sequence裡沒有其他sequence了 orz...
2.不想對程式變動太大 就自己包
選用2之後 程式就可以跑了 (萬分感謝)
但之後的程式又爆了orz...我再來慢慢debug
※ 引述《sbrhsieh (sbr)》之銘言:
: ※ 引述《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)
說實在是完全解決了我的問題 我的疑惑
跟我的無知...
見笑了 請見諒...orz
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.112.63.180
推
06/09 14:28, , 1F
06/09 14:28, 1F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 5 之 5 篇):
Python 近期熱門文章
PTT數位生活區 即時熱門文章