从C++调用 Python 类方法,如果给定一个初始化的类作为 PyObject
Calling a Python class method from C++, if given an initialised class as PyObject
我在 c++ 中有一个函数,它接收一个初始化的类作为 PyObject。 python类是:
class Expression:
def __init__(self, obj):
self.obj = obj
def get_source(self):
#Check if the object whose source is being obtained is a function.
if inspect.isfunction(self.obj):
source = inspect.getsourcelines(self.obj)[0][1:]
ls = len(source[0]) - len(source[0].lstrip())
source = [line[ls:] for line in source]
#get rid of comments from the source
source = [item for item in source if item.lstrip()[0] != '#']
source = ''.join(source)
return source
else:
raise Exception("Expression object is not a function.")
c++ 接收以下内容:
Expression(somefunctogetsource)
从 c++ 如何调用表达式对象的 get_source 方法? 到目前为止,我已经阅读了python c-api文档并尝试了这样的事情:
PyObject* baseClass = (PyObject*)expression->ob_type;
PyObject* func = PyObject_GetAttrString(baseClass, "get_source");
PyObject* result = PyObject_CallFunctionObjArgs(func, expression, NULL);
并将结果转换为字符串,但这不起作用。
比你做的更简单。无需直接从基类中检索任何内容。只需做:
PyObject* result = PyObject_CallMethod(expression, "get_source", NULL);
if (result == NULL) {
// Exception occurred, return your own failure status here
}
// result is a PyObject* (in this case, it should be a PyUnicode_Object)
PyObject_CallMethod
采用一个对象来调用方法,一个 C 样式字符串作为方法名称,一个格式字符串 + varargs 作为参数。当不需要参数时,可以NULL
格式字符串。
生成的PyObject*
对于C++代码不是非常有用(它运行时确定了 1、2 或 4 个字节字符,具体取决于所涉及的序数,因此从它直接将内存复制到std::string
或std::wstring
将不起作用),但PyUnicode_AsUTF8AndSize
可用于获取 UTF-8 编码版本和长度,可用于有效地构建具有等效数据的std::string
。
如果性能很重要,您可能希望在模块加载期间显式创建一个表示"get_source"
的PyObject*
,例如使用全局如下:
PyObject *get_source_name;
在模块的PyMODINIT_FUNC
中初始化为:
get_source_name = PyUnicode_InternFromString("get_source");
一旦有了它,您就可以将更有效的PyObject_CallMethodObjArgs
用于:
PyObject* result = PyObject_CallMethodObjArgs(expression, get_source_name, NULL);
节省的主要原因是避免一遍又一遍地从 Cchar*
构造 Python 级别的str
,并且通过使用PyUnicode_InternFromString
构造字符串,您可以使用暂留的字符串,使查找更有效(因为当在解释器中def
-ed 时,get_source
的名称本身会自动扣留, 不会对内容进行实际内存比较;它意识到这两个字符串都被扣留了,并且只检查它们是否指向相同的内存)。
- 构造函数在退出函数时无法初始化一个参数
- C++,每个循环初始化一个新的静态变量
- 初始化一个由 p 指向的新 INTSTK,它最多可以存储 m 个
- 如何初始化一个标准::字符串数组?
- 我们如何初始化一个C++中所有值为 0 的向量
- 为什么部分初始化一个类然后调用委托 ctor 失败?
- 从另一个常量标准::映射初始化一个常量标准::映射的一部分
- 如何初始化一个很长的数组?
- 如何声明和初始化一个特定尺寸向量的2D数组
- 初始化一个类型向量的巨大向量<int>
- 视觉C++似乎正在零初始化一个不应该的类的 POD 成员
- C 初始化一个变量并使用std :: cin分配
- C 宏从.CPP初始化一个在.h中声明的变量
- 在编译时初始化一个C++结构,就像一个未知绑定的数组
- 如何在另一个结构 arrya 中的一个结构中初始化一个 int 数组
- Dlib:如何初始化一个忽略标志设置为1的mmodrect
- 直接使用初始化器列表只能使用一个数组作为成员初始初始化一个构造是合法的吗?
- 使用 std::uniform_real_distribution 初始化一个 N 大小的 std::vector<double>
- 如何初始化一个在C++中期望向量和变量的构造函数<int>?
- 我如何在C 中初始化一个空对象