Hi!

I'm trying to build a Python extension with C/C++. I'm following the steps given in the documentation here. I've followed the steps mentioned and written my first code.

However, I have no clue on how to compile the project! I do not know how to create the .pyd file from the C code I have. I'm trying to figure out the arguments to be given to gcc (or g++), but all my attempts have been unsuccessful.

I first created the object file with the following command:

~$ gcc -c -fpic -I /usr/include/python2.6/ spamify.c

Which created the object file for me. How should I (now) create the .pyd file from the object file? I tried the following two commands -

gcc -shared -o spamify.pyd spamify.o

and

gcc -shared spamify.o -o _spamify.so

Both compiled fine and created the .so or .pyd file, but neither of them import into python. I got the following error (when importing):

>>> import spamify
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named spamify

I also tried

gcc -shared spamify.o -o _spamify.pyd

Again, it compiled fine (to give me _spamify.pyd). However, the error when trying to import was:

>>> import _spamify
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (init_spamify)

It looks like I'm horribly confused and making some fairly stupid error. But, I just cannot get past this. Any help would be awesome!

Thanks
Kedar

Here is my code (spamify.c)

#include <Python.h>

#include <stdio.h>
#include <stdlib.h>


static PyObject *spam_system(PyObject *self, PyObject *args)
{
    const char *command;
    int sts;

    if (!PyArg_ParseTuple(args, "s", &command))
        return NULL;
    sts = system(command);
    return Py_BuildValue("i", sts);
}

static PyMethodDef SpamMethods[] = {
    {"system",  spam_system, METH_VARARGS,"Execute a shell command."},
    {NULL, NULL, 0, NULL}        /* Sentinel */
};

PyMODINIT_FUNC init_spamify(void)
{
    (void) Py_InitModule("spamify", SpamMethods);
}

int main(int argc, char *argv[])
{
    /* Pass argv[0] to the Python interpreter */
    Py_SetProgramName(argv[0]);

    /* Initialize the Python interpreter.  Required. */
    Py_Initialize();

    /* Add a static module */
    init_spamify();
}

I removed the underscores before 'spamify' and it works

#include <Python.h>

#include <stdio.h>
#include <stdlib.h>


static PyObject *spam_system(PyObject *self, PyObject *args)
{
    const char *command;
    int sts;

    if (!PyArg_ParseTuple(args, "s", &command))
        return NULL;
    sts = system(command);
    return Py_BuildValue("i", sts);
}

static PyMethodDef SpamMethods[] = {
    {"system",  spam_system, METH_VARARGS,"Execute a shell command."},
    {NULL, NULL, 0, NULL}        /* Sentinel */
};

PyMODINIT_FUNC initspamify(void)
{
    (void) Py_InitModule("spamify", SpamMethods);
}

int main(int argc, char *argv[])
{
    /* Pass argv[0] to the Python interpreter */
    Py_SetProgramName(argv[0]);

    /* Initialize the Python interpreter.  Required. */
    Py_Initialize();

    /* Add a static module */
    initspamify();
}

Build (linux):

$ gcc -c -fPIC -I/usr/include/python2.6/ spamify.c
$ gcc -shared -o spamify.so spamify.o -L/usr/lib64/ -lpython2.6

Test:

>>> import spamify
>>> spamify.system("date")
ven. févr. 26 08:23:18 CET 2010
0

An alternative is to replace "spamify" by "_spamify" in the call to Py_InitModule.

commented: thanks for helping on that +10

Hi!

Thanks a lot.

Also, there seemed to be another error I was making. I was leaving the Python interpreter open after loading the module. Was having some permission issues as well, that I had no clue about!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.