【问题标题】:Extension Python by C++: How to determine python function name on C callbackC++ 扩展 Python:如何在 C 回调中确定 Python 函数名
【发布时间】:2014-04-17 14:04:33
【问题描述】:

我通过 C++ 扩展了 Python 并带有 Python API。 有一个用于不同 python 函数的 c 函数处理程序。 如何在 c 函数处理程序中确定调用我的 python 函数? 处理程序参数 PyObject* self 为 null...

我有一个方法表

<...>
PyObject* pyCallBackFunction(PyObject* self, PyObject* args, PyObject* kw){
// how i can determine here what python function called me?
// self = 0x00 on callback...
}
<...>
std::vector<char*> pyFuncs;
pyFuncs.push_back("Main");
pyFuncs.push_back("testMethod");
pyFuncs.push_back("func3");
this->PyMethodDefTable = (PyMethodDef*) malloc(sizeof(PyMethodDef)*(pyFuncs.size()+1));
for (unsigned int i=0; i<pyFuncs.size();++i){
  this->PyMethodDefTable[i] = (PyMethodDef) {pyFuncs[i],pyCallBackFunction,METH_KEYWORDS,pyFuncs[i]};}
PyMethodDef nullDef = (PyMethodDef){NULL, NULL, 0, NULL};
this->PyMethodDefTable[pyFuncs.size()] = nullDef ;
<...>
PyObject *m = Py_InitModule("testModule", this->methodsTable);

Python 调用:

import testModule
def Main():
  res1 = testModule.testMethod(arg1="test string", arg2= 34)
  res2 = testModule.func3(arg1="test string2", arg2= 434)
  return 1

感谢您的帮助!

【问题讨论】:

  • 为什么不让testMethod()func3() 成为一个小函数,用一个额外的参数调用公共代码?

标签: python c++ c embedding


【解决方案1】:

您可以调用PyEval_GetFrame(),它会为您提供指向当前框架对象的指针PyFrameObject 这个对象有一个名为f_code 的成员,它是一个PyCodeObject,这个代码对象有一个名为co_name 的成员,它是PyObject 实际上是一个字符串,您可以从中提取您所在的函数的名称。

从 python 本身可以使用sys._getframe(0).f_code.co_name 访问它

【讨论】:

  • 感谢您的评论!这种方法是线程安全的吗?这似乎是一个黑客......
  • CPython 没有什么是线程安全的。您对解释器所做的一切都需要使用 PyGILState_Ensure()PyGILState_Release() 锁定 GIL 来完成
  • 我已经编写了您的解决方案,但它返回的不是被调用函数的名称,而是高级函数的名称。 (在我的情况下它返回“Main”)解决方案: PyFrameObject* backTrace = PyEval_GetFrame(); PyCodeObject* 代码 = ((_frame*)backTrace)->f_code; PyObject* funcName = code->co_name; char* strFuncName = PyString_AS_STRING(funcName);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-12
相关资源
最近更新 更多