Передача аргументов в функцию Python через переполнение стека

Я использую программу C ++, и мне нужно вызывать объекты Python из программы C ++ (для выполнения оптимизации и математических операций). У меня проблемы с передачей аргументов объекту Python через C ++
Вот простой код

#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();
}

и класс питона

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 add (когда я вызываю PyObject_CallMethod (pInstance, «add», «i», x)). Вызов метода print через 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).

0

Решение

В соответствии с документы PyObject_CallMethod, строка формата должна создавать кортеж. Кроме того, не игнорируйте возвращаемое значение. Пытаться

PyObject *pValue;
pValue = PyObject_CallMethod(pInstance, "add","(i)",x);
if (pValue)
Py_DECREF(pValue);
else
PyErr_Print();
0

Другие решения

То, что работало для меня, было чем-то вроде этого python init и method:

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'

Я смог вызвать функцию из кода 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);
0

По вопросам рекламы [email protected]