user15995231
user15995231

Reputation:

How to make simple Hello World c module for python?

For the past few hours, I've been trying to build and run a simple c module that prints "hello world!!". I've run into a problem that I can't seem to work out:

importing the module:

import hi

Traceback (most recent call last):

  File "<ipython-input-1-746bfab23d87>", line 1, in <module>

    import hi

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xae in position 2: invalid start byte

hellomodule.c:

#include <Python.h>


static PyObject *hello(void);


static PyMethodDef module_methods[] = {
    
    {"hello", hello, METH_VARARGS},
    
    {NULL, NULL, 0}
    
};


PyMODINIT_FUNC PyInit_hi(void)

{
 
    PyObject *module;
    
    static struct PyModuleDef moduledef = {
        
        PyModuleDef_HEAD_INIT,
        
        "hi",
        
    module_methods,
    
        NULL,
        
        NULL,
        
    NULL,
    
    };
    
    module = PyModule_Create(&moduledef);
    
    return module;

}


static PyObject *hello(void)

{
 
    printf("%s", "hello world");
    
    return Py_BuildValue("Pls Work");

    }

setup.py:

from distutils.core import setup, Extension


module1 = Extension('hi', sources=['hellomodule.c'])

setup(name='MyExtension',
      
       version='1.0',
       
       description='This is a demo extension',
       
       ext_modules=[module1])

The actual module I'm importing is obviously a .pyc created from "setup.py build". This code is for a windows environment. Any help is appreciated!! Thanks!!

Upvotes: 1

Views: 260

Answers (1)

lemonhead
lemonhead

Reputation: 5518

Main issue is down to how you initialize the PyModuleDef def struct. As you can see from the documentation, you need to pass in module_methods as the 5th argument rather than 3rd, among other key arguments:

PyMODINIT_FUNC PyInit_hi(void)
{
    PyObject *module;
    
    static struct PyModuleDef moduledef = {
        PyModuleDef_HEAD_INIT,
        "hi",
        NULL,
        -1,
        module_methods,
    };
    module = PyModule_Create(&moduledef);
    return module;
}

Additionally, within the hello function itself you probably wanted a newline if you want to immediately flush your print statement, and Py_BuildValue needs to be passed the appropriate format char to return a string:

static PyObject *hello(void)
{
    printf("%s", "hello world\n");
    return Py_BuildValue("s", "Pls Work");
}

Upvotes: 1

Related Questions