user2738965
user2738965

Reputation: 29

C & python integration

When i run this code

./call try1 getByteLength '127 89 89'

it only accepts 127 as its argument and ignore the rest of it. [getByteLength] is just name of python function that i am calling from C.

I have use this code from python official page:

How can i do this ?

#include <Python.h>

int main(int argc, char *argv[]) {
Py_Initialize();
    PyRun_SimpleString("import sys");
        PyRun_SimpleString("import binascii");
        PyRun_SimpleString("sys.path.append(\".\")");
        PyObject *pName, *pModule, *pDict, *pFunc;
        PyObject *pArgs, *pValue;
        int i;

        if (argc < 3) {
            fprintf(stderr,"Usage: call pythonfile funcname [args]\n");
            return 1;
        }

        //Py_Initialize();
        pName = PyString_FromString(argv[1]);
        /* Error checking of pName left out */

        pModule = PyImport_Import(pName);
        Py_DECREF(pName);

        if (pModule != NULL) {
            pFunc = PyObject_GetAttrString(pModule, argv[2]);
            /* pFunc is a new reference */

        if (pFunc && PyCallable_Check(pFunc)) {
                pArgs = PyTuple_New(argc - 3);
                for (i = 0; i < argc - 3; ++i) {
                    pValue = PyInt_FromLong((argv[i + 3]));
                    if (!pValue) {
                       Py_DECREF(pArgs);
                       Py_DECREF(pModule);
                       fprintf(stderr, "Cannot convert argument\n");
                       return 1;
                    }
                    /* pValue reference stolen here: */
                    PyTuple_SetItem(pArgs, i, pValue);
            }
                pValue = PyObject_CallObject(pFunc, pArgs);
                Py_DECREF(pArgs);
                if (pValue != NULL) {
                printf("Result of call: %ld\n", PyInt_AsLong(pValue));
                Py_DECREF(pValue);
                }
                else {
                    Py_DECREF(pFunc);
                    Py_DECREF(pModule);
                    PyErr_Print();
                    fprintf(stderr,"Call failed\n");
                    return 1;
                }
        }
        else {
            if (PyErr_Occurred())
                    PyErr_Print();
                    fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);
        }
            Py_XDECREF(pFunc);
            Py_DECREF(pModule);
    }
    else {
            PyErr_Print();
            fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);
            return 1;
    }
        Py_Finalize();
        return 0;
}

Upvotes: 0

Views: 181

Answers (2)

user2738965
user2738965

Reputation: 29

Instead of PyInt, I used PyString. It doesn't need any conversion.

pValue = PyString_FromString(argv[i + 3]);

For other methods, please refer python documentation page.

Upvotes: 0

Aaron Digulla
Aaron Digulla

Reputation: 328810

When you use '127 89 89', that means the C code gets a single argument (a string with three numbers).

Then you call PyInt_FromLong((argv[i + 3])) which takes the address of the third argument and casts that to int (the address, it will ignore the content of the argument). This is basically a broken random number generator and won't do what you expect or need.

You should use PyInt_FromString() instead and use the pend pointer to move from one number in the string to the next. Note that you will probably have to skip the white space in the string yourself.

That said, I suggest to use ./call try1 getByteLength 127 89 89 (so you get each number in an individual argument) and then use PyInt_FromString() to parse each.

Upvotes: 2

Related Questions