Dan Dan - 1 year ago 108
Python Question

Building Python C extension

I need to create a new python module as a c extension for both performance and CUDA utilization. I have tried a couple of tutorials for this and was unsuccessful. Here are my files:


#include <Python.h>

static PyObject* say_hello(PyObject* self, PyObject* args)
const char* name;

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

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


static PyMethodDef HelloMethods[] =
{"say_hello", say_hello, METH_VARARGS, "Greet somebody."},

PyMODINIT_FUNC inithello(void)
(void) Py_InitModule("hello", HelloMethods);


from distutils.core import setup, Extension

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

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

And here is my result for
python setuphello.py build

running build
running build_ext
building 'hello' extension
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -IC:\Anaconda3\include -IC:\Anaconda3\include "-IC:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\winrt" "-IC:\Program Files (x86)\IntelSWTools\Trace Analyzer and Collector\\include" /Tchellomodule.c /Fobuild\temp.win32-3.5\Release\hellomodule.obj
hellomodule.c(23): warning C4013: 'Py_InitModule' undefined; assuming extern returning int
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:\Anaconda3\libs /LIBPATH:C:\Anaconda3\PCbuild\win32 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.10240.0\ucrt\x86" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x86" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.10240.0\um\x86" /EXPORT:PyInit_hello build\temp.win32-3.5\Release\hellomodule.obj /OUT:build\lib.win32-3.5\hello.cp35-win32.pyd /IMPLIB:build\temp.win32-3.5\Release\hello.cp35-win32.lib
LINK : error LNK2001: unresolved external symbol PyInit_hello
build\temp.win32-3.5\Release\hello.cp35-win32.lib : fatal error LNK1120: 1 unresolved externals
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\link.exe' failed with exit status 1120

I have looked at the various errors others have had and have tried following their debugging logic but am honestly at a loss as to what is happening behind the scenes that is causing my error. I am using Python 3.5 32-bit (Anaconda) and so have been trying to compile with the Visual C++ build tools and its packaged terminal. This doesn't make any difference however. Can someone please lead me in the right direction?

Answer Source

The problem with your approach is that you relied on tutorials/guides for Python 2.7.x (maybe this?) while you are using a Python 3.5.x interpreter.

The way to construct a C extension has changed in Python 3.x.

So, in order to make your 'hello' module compile you will have to make the appropriate changes in hellomodule.c:

First, add the following struct right above the inithello() function:

static struct PyModuleDef hellomodule = {
    "hello", /* module name */
    NULL, /* module documentation, may be NULL */
    HelloMethods /* the methods array */

Then replace the entire inithello() function with this instead:

PyMODINIT_FUNC PyInit_hello(void)
    return PyModule_Create(&hellomodule);

You do not have to make any changes to the setuphello.py script, which you can run as usual:

python setuphello.py build

You can quickly test your freshly compiled module by going into the build\lib.win32-3.5 directory (or something similar), copy the .pyd file (in my system it is named hello.cp35-win32.pyd) someplace convenient and there use something like this little script (usehello.py):

import hello

def greet(person):


Running yields:

c:\>python usehello.py
Hello stranger!


For a full description of the extension procedure, you can go to the official documentation for Python 3.5