私は決してアセンブリの専門家ではなく、コードを実行すると次のエラーが発生します。「ランタイムチェックの失敗#0-ESPの値が関数呼び出し全体で適切に保存されませんでした。」
私は現在、CPythonライブラリを使用してCスタイルの関数をPython 3.2にバインドする作業を行っていますが、コードでdoubleを渡す際に問題が発生しました。そのようにプロトタイプ化されたC関数を呼び出すために使用される単一のテンプレート関数があります。
template <const char* MODULE, const char* FUNCTION>
static PyObject* ModuleFunction (PyObject* self, PyObject* param);
現在、私のメソッドはPythonとC / C ++の間で整数型を渡すために機能しますが、doubleで問題が発生しています。たぶん、x86アセンブリに精通している人が、私が間違っていることに気付くことができます。スニペットにdoubleを含まないすべてのコードを抽出しました。
__asm
{
mov ecx, num_params
mov ebx, 0
cmp ebx, ecx
je functionCall
extractParameters:
mov ebx, ecx
dec ebx
push ecx // save ecx
push ebx
push param
call Py_GrabElementFromTuple
pop edx // I know I could modify esp, but this made it more readable to me
pop edx
push eax // push the returned PyObject* onto the stack
mov edx, 0
mov ecx, dword ptr [paramTypes]
mov dl, byte ptr [ecx+ebx]
cmp decimal, edx
je extractDouble
jmp endLoop
extractDouble:
call Py_ExtractDouble
pop ebx
pop ecx
fstp qword ptr [esp]
jmp endLoop
endLoop:
loop extractParameters
functionCall:
call func
mov ecx, dword ptr [stacksize]
add esp, ecx
mov edx, returnType
cmp decimal, edx
je wrapDouble
jmp done
wrapDouble:
fstp qword ptr [esp]
call Py_WrapDouble
mov returnObj, eax
jmp done
done:
}
私が使用した次の関数についての説明は、誰にとっても明確ではないかもしれません。
PyObject* Py_GrabElementFromTuple(PyObject* tuple, int index);
PyObject* Py_WrapDouble(double d);
double Py_ExtractDouble(PyObject* obj);
上記の関数はすべて、エラーチェックを追加するためにCPythonメソッドの周りに書いたラッパーです。