3

I'm trying to load a python module that contains a math and numpy import in C, using the C API. I can load and run the module but, if I import the math module it doesn't work.

I'm using Arch Linux, Python 2.7.2 and gcc.

Here the codes:

#include <stdio.h>
#include <stdlib.h>
#include <python2.7/Python.h>


int main(int argc, char **argv)
{
    PyObject *pName, *pModule, *pFunc, *pArg, *pDict, *pReturn, *pT1, *pT2, *pX, *pY;
    int i;
    double x, y;

    Py_Initialize();

    PySys_SetPath(".");

    pName = PyString_FromString("func");
    if (!pName)
    {
        printf("pName\n");
        return 0;
    }
    pModule = PyImport_Import(pName);

    pDict = PyModule_GetDict(pModule);
    pFunc = PyDict_GetItemString(pDict, "get_vals");
    pArg = PyTuple_New(2);
    PyTuple_SetItem(pArg, 0, PyFloat_FromDouble(4.0));
    PyTuple_SetItem(pArg, 1, PyFloat_FromDouble(2.0));
    pReturn = PyObject_CallObject(pFunc, pArg);
    pT1 = PyTuple_GetItem(pReturn, 0);
    pT2 = PyTuple_GetItem(pReturn, 1);

    for (i = 0; i < PyTuple_Size(pT1); i++)
    {
        pX = PyTuple_GetItem(pT1, i);
        pY = PyTuple_GetItem(pT2, i);
        x = PyFloat_AsDouble(pX);
        y = PyFloat_AsDouble(pY);
        Py_XDECREF(pX);
        Py_XDECREF(pY);
        pX = NULL;
        pY = NULL;
        printf("Point p position is: %.2fx, %.2fy", x, y);
    }

    Py_XDECREF(pName); Py_XDECREF(pModule); Py_XDECREF(pFunc); Py_XDECREF(pArg); Py_XDECREF(pDict); Py_XDECREF(pReturn); Py_XDECREF(pT1); Py_XDECREF(pT2);

    Py_Finalize();

    return 0;
}

func.py

from math import cos

def get_vals(width, height):
    x = (1, 2)
    y = (cos(3), 4)

    return x, y

And how can I embbed the Python script to C without need to use the script?

1
  • I got a segmentation fault after the program try to load the module... Now I'll try to use PyRun_SimpleString. Commented Oct 2, 2011 at 16:18

1 Answer 1

16

The PySys_SetPath(".") cleared the python path, so it could no longer find any library whatsoever. What you really need to do is import sys.path and then append your string to it:

PyObject *sys = PyImport_ImportModule("sys");
PyObject *path = PyObject_GetAttrString(sys, "path");
PyList_Append(path, PyString_FromString("."));

(I didn't test the above code, but it should be close. Also, you should do error checking)

Sign up to request clarification or add additional context in comments.

2 Comments

I'm using Python 3.7 and PyString_FromString doesn't exist there. Took me a little bit but I thought somebody would find this helpful: Use PyUnicode_FromString
You can also just append the path in the python language itself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.