0

I am trying to extend python using a simple C file. I succeeded in creating my own python module, but I also need the C file itself to compile and run as a standalone executable. I can successfully compile it, but when I try to run it I get the error "cannot execute binary file: Exec format error".

Here is my C source file (hellomodule.c):

#include <Python.h>

void print_hello(const char* name){
    printf("Hello %s!\n", name);
}

//Only used by Python
static PyObject*
say_hello(PyObject* self, PyObject* args)
{
    const char* name;

    if (!PyArg_ParseTuple(args, "s", &name))
        return NULL;

    //printf("Hello %s!\n", name);
    print_hello("World");

    Py_RETURN_NONE;
}

//Only used by Python
static PyMethodDef HelloMethods[] =
{
    {"say_hello", say_hello, METH_VARARGS, "Greet somebody."},
    {NULL, NULL, 0, NULL}
};

//Only used by Python
PyMODINIT_FUNC
inithello(void)
{
    (void) Py_InitModule("hello", HelloMethods);
}

int main(){
    print_hello("World");
}

I can "successfully" compile it without any errors or warnings with the following:

gcc -I /usr/include/python2.7 -c hellomodule.c -o hellomodule

After making the "hellomodule" file executable, I run it and get the error:

-bash: ./hellomodule: cannot execute binary file: Exec format error

Why would this be causing such an error?

2
  • You are not supposed to execute the module!!! Commented Jan 7, 2016 at 22:48
  • 1
    -c means "compile". This stage produces object files, not binaries. Commented Jan 7, 2016 at 22:49

1 Answer 1

1

You are trying to execute an object file, that is not an executable. To compile your code as a module you need something like

gcc -Wall -Werror -Wextra -O2 -I/usr/include/python2.7 \
    -shared hellomodule.c -o hellomodule.so -lpython2.7

but to link correctly to everything and add all the possible include directories there is a script called python-config you just need to invoke it like this

gcc -Wall -Werror -Wextra -O2 `python-config --includes` \
    -shared hellomodule.c -o hellomodule.so `python-config --libs`

and even better, the script providesCFLAGS and LDFLAGS too, so finally

gcc -Wall -Werror -Wextra -O2 `python-config --cflags` \
    -shared hellomodule.c -o hellomodule.so `python-config --ldflags`

and then, copy the resulting file to /usr/lib/python2.7/site-packages.

After that, you can load the module in a python script like this

import hellomodule

Object files are intermediate binary files used ultimately by the linker (ld probably) to produce the final binary. A python module has no main() function and it has to be a runtime loadable shared object which exports some predefined symbols that the python interpreter will use to load the module into the python script/program.

Note: To correctly do this and not die trying create a Makefile, like this

CFLAGS = `python-config --cflags` -Wall -Werror # add more if needed
LDFLAGS = `python-config --ldflags` # add more if needed
OBJS = hellomodule.o # add more if needed

all: $(OBJS)
    $(CC) $(CFLAGS) $(LDFLAGS) -shared -o modulename.so $(OBJS)

%.o: %.c
    $(CC) -c $(CFLAGS) $<

ensure that you use tabs instead of spaces for indentation, and then run make in the same directory where the Makefile and the source files are.

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

3 Comments

Ok, I didn't know what the "-c" option meant. When I take it out it says I have a bunch of undefined references to python objects. Also, in the question I said that I already have the python module working. I am trying to get the C file to compile and run on its own.
Yes because you need -lpython2.7, let me edit the answer.
Thanks! I added the "-lpython2.7" and now it compiles and runs correctly!

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.