I'm trying to work out how to make a Python extension with C++; I have a simple "hello world"-level test program that will compile with distutils and run fine on Linux (Ubuntu), but which fails on Windows. I'm using 64-bit Python 2.7 on Windows 7.
The test case is three files:
setup.py
foobar/__init__.py
foobar/testext.cpp
setup.py
:
from distutils.core import setup, Extension
setup(name = "foobar",
packages = ['foobar'],
ext_modules = [Extension('foobar/test',
sources = ['foobar/testext.cpp'])])
foobar/__init__.py
: (I guess this is unnecessary?)
import test
def foobar():
return test.testfunc() * 10
foobar/testext.cpp
:
# include <Python.h>
static PyObject * test_func(PyObject *self, PyObject *args)
{
return Py_BuildValue("i", 6);
};
static PyMethodDef TestMethods[] = {
{"testfunc", test_func, METH_VARARGS, "Blah."},
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC inittest(void)
{
(void) Py_InitModule("test", TestMethods);
}
This compiles with "setup.py build" without complaint. However, if I then go into the lib directory and try to import the package, it gives an error:
Python 2.7.6 (default, Nov 10 2013, 19:24:24) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import foobar
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "foobar\__init__.py", line 1, in <module>
import test
ImportError: DLL load failed: %1 is not a valid Win32 application.
I'm aware that this error message typically indicates trying to load a 32-bit binary with a 64-bit copy of Python, but oddly I get the same message if I try to import the module with a 32-bit copy of Python. Meanwhile the same procedure with the same files works on Ubuntu. Any ideas?
Correction: I goofed; when I actually delete the pre-existing "build" directory and recompile, it does give an error. I thought updating my copy of setuptools had fixed this, but instead what was happening was the terminal command "del build" was just quietly not doing anything (argh, Windows!).
Running setup.py build
shows:
C:\Users\Max\Downloads\worksonlinux\pyextstuff>setup.py build
running build
running build_py
creating build
creating build\lib.win-amd64-2.7
creating build\lib.win-amd64-2.7\foobar
copying foobar\__init__.py -> build\lib.win-amd64-2.7\foobar
running build_ext
building 'foobar/test' extension
creating build\temp.win-amd64-2.7
creating build\temp.win-amd64-2.7\Release
creating build\temp.win-amd64-2.7\Release\foobar
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\amd64\cl.exe /c /nologo /Ox /MD /W3 /GS- /DNDEBUG -I
C:\Python27\include -IC:\Python27\PC /Tpfoobar/testext.cpp /Fobuild\temp.win-amd64-2.7\Release\foobar/testext.
obj
testext.cpp
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\amd64\link.exe /DLL /nologo /INCREMENTAL:NO /LIBPATH
:C:\Python27\libs /LIBPATH:C:\Python27\PCbuild\amd64 /EXPORT:initfoobar/test build\temp.win-amd64-2.7\Release\
foobar/testext.obj /OUT:build\lib.win-amd64-2.7\foobar\test.pyd /IMPLIB:build\temp.win-amd64-2.7\Release\fooba
r\test.lib /MANIFESTFILE:build\temp.win-amd64-2.7\Release\foobar\test.pyd.manifest
LINK : error LNK2001: unresolved external symbol initfoobar/test
build\temp.win-amd64-2.7\Release\foobar\test.lib : fatal error LNK1120: 1 unresolved externals
error: command '"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\amd64\link.exe"' failed with exit s
tatus 1120