我无论如何都不是组装专业人士,并且在运行我的代码时收到以下错误:“运行时检查失败 #0 - ESP 的值未在函数调用中正确保存。”
我目前正在使用 CPython 库将 C 样式函数绑定到 Python 3.2,并且在我的代码中遇到了传递双精度数的问题。我有一个模板函数,用于调用原型如下的 C 函数:
template <const char* MODULE, const char* FUNCTION>
static PyObject* ModuleFunction (PyObject* self, PyObject* param);
目前,我的方法适用于在 Python 和 C/C++ 之间传递整数类型,但我在使用双精度时遇到了问题。也许更精通 x86 汇编的人可以发现我做错了什么。我已经在我的代码段中提取了所有不涉及双精度的代码:
__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 方法编写的用于添加错误检查的包装器。