16

I am a newbie in python, so may be this is a silly question. I want to write simple c program with embedded python script. I have two files:

call-function.c:

    #include <Python.h>
    int main(int argc, char *argv[])
    {
        PyObject *pName, *pModule, *pDict, *pFunc, *pValue;

        if (argc < 3)
        {
            printf("Usage: exe_name python_source function_name\n");
            return 1;
            }

        // Initialize the Python Interpreter
        Py_Initialize();

        // Build the name object
        if ((pName = PyString_FromString(argv[1])) == NULL) {
            printf("Error: PyString_FromString\n");
            return -1;
        }

        // Load the module object
        if ((pModule = PyImport_Import(pName)) == NULL) {
            printf("Error: PyImport_Import\n");
            return -1;
        }

        // pDict is a borrowed reference 
        if ((pDict = PyModule_GetDict(pModule))==NULL) {
            printf("Error: PyModule_GetDict\n");
            return -1;
        }
...

and

hello.py:

def hello():
    print ("Hello, World!")

I compile and run this as follows:

gcc -g -o call-function call-function.c -I/usr/include/python2.6 -lpython2.6
./call-function hello.py hello

and have this:

Error: PyImport_Import

i.e. PyImport_Import returns NULL. Could you help me with this issue? Any help will be appreciated.

Best wishes,

Alex

viraptor
  • 33,322
  • 10
  • 107
  • 191
Alexander
  • 713
  • 1
  • 7
  • 20
  • 7
    you forgot the step where you draw a pentagon in chicken blood and light the black candles :P .... thats what usually works for me when mixing C and Python – Joran Beasley Jul 08 '13 at 17:27
  • 1
    Looks like `argv[0]` will be the exe name, `argv[1]` will be `hello.py`, and `argv[2]` will be `hello`. Do you want to import something else instead of `argv[1]`? You need the module name not the source file name right? – Brian Jul 08 '13 at 17:32
  • Yes, that is right. But I thought that module name is the same as file name. Is it correct? – Alexander Jul 08 '13 at 17:41
  • 4
    The module name is `hello`. It's the same for standard python scripts. You couldn't run `python -c "import hello.py"` from the local directory either. – viraptor Jul 08 '13 at 17:53

4 Answers4

21

I have resolved this issue by setting PYTHONPATH to pwd. Also module name (without .py) should be set for argv[1].

Thank you!

Alexander
  • 713
  • 1
  • 7
  • 20
6

I ran into this issue also after struggling for a while.After searching the web I found that is was a system path issue. After adding the two lines after Py_Initialize(); it worked.

OS: Windows 7, Compiler: Embarcadero C++ Builder XE6, Python: Version 2.7

Reference: C++ With Python

Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\"C:\\Python27\")");
Chad
  • 273
  • 3
  • 8
  • 19
  • I am having the same problem and added the 2 lines you recommend, changing the path.append to "c:\python35" where my python libs and DLLs exist but it didn't help me. PyImport_Import() always returns NULL. – James Dec 18 '15 at 00:15
  • I tried Alexander's solution with and without your recommendation and it didn't seem to make a difference. However, I'm keeping it in just in case. ;-) – James Dec 18 '15 at 00:24
  • Works well on Linux too. – Ash Dec 11 '18 at 12:14
4

If the python source file is located in the working directory (i.e. where the *.cpp files of the project reside), you can use...

PyRun_SimpleString("sys.path.append(os.getcwd())");

...to add the working directory to the Python path.

chb
  • 1,727
  • 7
  • 25
  • 47
Alfons
  • 41
  • 2
0

This is an obscure case but my python function was importing code that required argv to be set. In order to fix that I had to add:

PySys_SetArgv(argc, argv);

after the Py_Initialize() call and it started working.