1

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!!

1 Answer 1

1

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");
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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