1

我正在使用 C++ 程序,我需要从 C++ 程序中调用 Python 对象(以执行优化和数学运算)。我无法通过 C++ 将参数传递给 Python 对象这是一个简单的代码

#include <Python.h>
#include <iostream>
#include <cstdio>
#include <cstdlib>

int main()
{
    PyObject *pName, *pModule, *pDict, *pClass, *pInstance;

    // Initialize the Python interpreter
    Py_Initialize();

    // Build the name object
    pName = PyString_FromString("Adder");
    // Load the module object
    pModule = PyImport_Import(pName);
    // pDict is a borrowed reference
    pDict = PyModule_GetDict(pModule);
    // Build the name of a callable class
    pClass = PyDict_GetItemString(pDict, "Adder");
    // Create an instance of the class
    if (PyCallable_Check(pClass))
    {
        pInstance = PyObject_CallObject(pClass,NULL);
    }
    else
    {
        std::cout << "Cannot instantiate the Python class" << std::endl;
    }

    int sum = 0;
    int x;

    for (size_t i = 0 ; i < 5 ; i++)
    {
        x = rand() % 100;
        sum += x;
        PyObject_CallMethod(pInstance, "add","(i)",x);
    }
    PyObject_CallMethod(pInstance, "printSum", NULL);
    std::cout << "the sum via C++ is " << sum << std::endl;

    std::getchar();
    Py_Finalize();
}

和python类

class Adder:
    # Constructor
    def __init__(self):
        self.sum = 0

    # Add an element to the Adder
    def add(self,x):
        print "adding via python ", x
        self.sum += x


    # Print the total sum
    def printSum(self):
        print "the sum via the Python class is ",self.sum

不幸的是,参数x没有通过python方法添加(当我调用PyObject_CallMethod(pInstance,“add”,“i”,x))通过python调用打印方法给我“通过Python类的总和是0” . 向 python 方法提供数字的最佳方法是什么?

非常感谢你的帮助

文森特

PS:我在python中定义了一个双重加法函数

def add2(self,x,y):
    print "double adding via python"
    self.sum += x*y

在 C++ 中调用以下命令

PyObject_CallMethod(pInstance, "add2","(ii)",x,2);

正在工作...看来我的格式 (i) 有问题。

4

2 回答 2

1

根据的文档PyObject_CallMethod,格式字符串应该产生一个元组。另外,不要忽略返回值。尝试

PyObject *pValue;
pValue = PyObject_CallMethod(pInstance, "add","(i)",x);
if (pValue)
    Py_DECREF(pValue);
else
    PyErr_Print();
于 2013-05-16T10:11:05.533 回答
0

对我有用的是这样的 python init 和方法:

class SwiftApi:
    def __init__(self, user, key):
        self.user = user
        self.key = key

蟒蛇方法

def get_object(self, container, obj, resp_chunk_size=None,
               query_string=None):
    return 'some returned object here'

我可以用这个 hack 从 c++ 代码调用函数

#include <python2.7/Python.h>
void error_abort(void)
{
    PyErr_Print();
    exit(EXIT_FAILURE);
}
int main (int argc, char *argv[])
{
PyObject  *user, *key, *args, *md_module, *attr, *instance, *get_obj_tuple, *container, *obj,*methodcall,
Py_Initialize();


if (!(user = PyString_FromString("test:tester")))
    error_abort();


if (!(key = PyString_FromString("testing")))
    error_abort();

if (!(args = PyTuple_Pack(5,type, user, key, secret_key, authurl)))
    error_abort();
PySys_SetPath("the path where the py file lives");

if (! (md_module = PyImport_ImportModule("SwiftApi")))
    error_abort();

if (md_module != 0) {
printf ("got it middleware_module- %s\n", md_module);
}
else{ printf ("NO md_module ");}

if (!(attr = PyObject_GetAttrString(md_module, "ObjectStorageMiddleware")))
    error_abort();

if (attr != 0) {
printf ("got the class- %s\n", attr);
}
if (!(instance = PyObject_CallObject(attr, args )))
    error_abort();
if (instance != 0) {
printf ("###############got it ObjStrgRes instance -  class- %d\n", (long)instance);
}
if (!(container = PyString_FromString("my-con-55")))
    error_abort();

if (!(obj = PyString_FromString("ohad2.jpg")))
    error_abort();



get_container_tuple = PyTuple_Pack(1, container);
get_obj_tuple = PyTuple_Pack(1, obj);



if (!(methodname = PyString_FromString("get_object")))
    error_abort();

methodcall = PyObject_CallMethodObjArgs(instance, methodname, get_container_tuple, get_obj_tuple, NULL);
于 2016-11-30T11:51:12.567 回答