2015-05-07 6 views
1

Я пытаюсь сделать вызов функции модуля python из моего файла cpp.Вызов функции Python из C++

Вызов я сделал это следующим образом:

#include <iostream> 
#include "Python.h" 

int 
main(int argc, char** argv) 
{ 
    Py_Initialize(); 
    PyObject *pName = PyString_FromString("tmpPyth"); 
    PyObject *pModule = PyImport_Import(pName); 
    std::cout<< "Works fine till here"; 
    PyObject *pDict = PyModule_GetDict(pModule); 
    if (pModule != NULL) { 
     PyObject *pFunc = PyObject_GetAttrString(pDict, "pyFunc"); 

     if(pFunc != NULL){ 
      PyObject_CallObject(pFunc, NULL); 
     } 
    } 
    else 
     std::cout << "Python Module not found"; 
    return 0; 
} 

Мой модуль питона определяется следующим образом:

import numpy 
import scipy 
import matplotlib 

from scipy import stats 
def blah(): 
     baseline = [9.74219, 10.2226, 8.7469, 8.69791, 9.96442, 9.96472, 9.37913, 9.75004] 
     follow_up = [9.94227,9.46763,8.53081,9.43679,9.97695,10.4285,10.159,8.86134] 
     paired_sample = stats.ttest_rel(baseline , follow_up) 
     print "The t-statistic is %.3f and the p-value is %.3f." % paired_sample 

код в файле CPP работает отлично до 1 «СТД :: cout ", но затем заканчивается тем, что дает мне« seg fault ». Запуск кода python работает отлично и дает желаемый результат.

Я не могу понять, что происходит не так. Любая помощь будет оценена. (Обратите внимание, что программа правильно и корректно компилируется до 1-го «cout»)

+0

Я могу вам сказать, что это segfaulting из 'PyObject * pDict = PyModule_GetDict (pModule);' , Похоже, что он не может загрузить модуль вообще. – vaidik

+0

В идеале эта строка должна быть в блоке if после того, как вы убедитесь, что модуль загружен. – vaidik

ответ

2

Итак, есть несколько вещей, которые вы не делали правильно. См. Комментарии в строке. Предположим, что и ваш файл CPP, и файл Python находятся по следующему пути: /home/shanil/project.

test.cpp:

#include <iostream> 
#include "Python.h" 

int 
main(int argc, char** argv) 
{ 
    Py_Initialize(); 

    // First set in path where to find your custom python module. 
    // You have to tell the path otherwise the next line will try to load 
    // your module from the path where Python's system modules/packages are 
    // found. 
    PyObject* sysPath = PySys_GetObject("path"); 
    PyList_Append(sysPath, PyString_FromString("/home/shanil/project")); 

    // Load the module 
    PyObject *pName = PyString_FromString("my_mod"); 
    PyObject *pModule = PyImport_Import(pName); 

    // Random use-less check 
    std::cout<< "Works fine till here\n"; 

    if (pModule != NULL) { 
     std::cout << "Python module found\n"; 

     // Load all module level attributes as a dictionary 
     PyObject *pDict = PyModule_GetDict(pModule); 

     // Remember that you are loading the module as a dictionary, the lookup you were 
     // doing on pDict would fail as you were trying to find something as an attribute 
     // which existed as a key in the dictionary 
     PyObject *pFunc = PyDict_GetItem(pDict, PyString_FromString("my_func")); 

     if(pFunc != NULL){ 
      PyObject_CallObject(pFunc, NULL); 
     } else { 
      std::cout << "Couldn't find func\n"; 
     } 
    } 
    else 
     std::cout << "Python Module not found\n"; 
    return 0; 
} 

my_mod.py:

def my_func(): 
    print 'got called'