いくつかの関数が公開されたCで記述されたPythonモジュールがあります。それらの1つには、次のPython定義があります。
def SetPowerSupply(voltage, current, supply):
ここで、電圧=フロート、電流=フロート、および供給=整数です。C側では、私はこれを持っています:
float voltage, current;
int supply;
if (!PyArg_ParseTuple(args, "ffi", &voltage, ¤t, &supply))
{
// Failed to parse
// ...
}
私のスクリプターの1人が、この関数が引数の解析に失敗し、整数が予期されていると文句を言うスクリプトを持っています。私が知る限り、エラーブランチの場合は次のようにするため、実際には整数が渡されます。
PyObject *num = PyNumber_Float(PyTuple_GetItem(args, 0));
voltage = PyFloat_AsDouble(num);
Py_XDECREF(num);
num = PyNumber_Float(PyTuple_GetItem(args, 1));
current = PyFloat_AsDouble(num);
Py_XDECREF(num);
num = PyNumber_Int(PyTuple_GetItem(args, 2));
supply = PyLong_AsLong(num);
Py_XDECREF(num);
...その後、すべてが期待どおりに機能します。このモジュールで実行されている他のスクリプトはこの動作を示さず、違いはわかりません。どちらも同じ関数を呼び出します。
SetPowerSupply(37.5, 0.5, 1)
SetPowerSupply(0, 0, 1)
問題のあるスクリプトでは、次のようなことができます。
何か案は???
ありがとうございました。
編集:
この問題は、この関数の前にいくつかの呼び出しが呼び出されていた別の関数が原因で発生しました。そうだった:
if(!PyArg_ParseTuple(args, "s|siss", &board, &component, &pin, &colorStr, &msg))
{
// Parsing the pin as an int failed, try as a string
if(!PyArg_ParseTuple(args, "s|ssss", &board, &component, &sPin, &colorStr, &msg))
{
// ...
これの目的は、基本的に3番目の引数をオーバーロードして、文字列または数値のいずれかを受け入れることでした。誰かがそれに文字列を供給したとき、失敗した解析からのPythonエラーは決してクリアされませんでした。問題を解決する更新されたコードは次のとおりです。
if(!PyArg_ParseTuple(args, "s|siss", &board, &component, &pin, &colorStr, &msg))
{
PyErr_Clear();
// Parsing the pin as an int failed, try as a string
if(!PyArg_ParseTuple(args, "s|ssss", &board, &component, &sPin, &colorStr, &msg))
{
// ...
手がかりを与えてくれたIgnacioに感謝します。