Backstory: For one of my projects that requires heavy computations, I am currently calling from my Python code an .exe coming from a C++ code, which read/write files on disk, and is thus super slow.
To solve this problem, I have recoded the C++ code to be used as a DLL in my Python code, since then there won't be disk access and it should be faster. To do this I plan to use Cython.
Problem: To understand better how it works, I am therefore following this tutorial, by J.J. Hakala who actually posts often here about Cython.
I followed every part, and I have in the same directory on Windows:
- the DLL file that I compiled with MS Visual Studio 2015 Express:
complexFunLib.dll
- the .lib file that comes with the DLL:
complexFunLib.lib
- the header file for the C++ DLL source:
complexFunLib.h
- the Cython "header" file:
ccomplexFunLib.pxd
(yes there is an extra 'c') - the Cython "wrapper" file:
complexFunLib.pyx
- the Python setup file for creating complexFunLib.pyd with Cython:
setup.py
When I tried to run python setup.py --build_ext --inplace
first it couldn't find the library so I had to use that trick from another SO question to tell where was the DLL, so in setup.py
I modified: libraries=[r'.\complexFunLib']
then that error disappeared.
Which brings me to my current unresolved error:
When I run python setup.py --build_ext --inplace
it uses MinGW and raises this error:
EDIT, I PUT THE FULL LOG:
running build_ext
cythoning complexFunLib.pyx to complexFunLib.cpp
building 'complexFunLib' extension
creating build
creating build\temp.win-amd64-3.6
creating build\temp.win-amd64-3.6\Release
D:\MYNAME\AppData\Local\Continuum\Anaconda3\Library\mingw-w64\bin\gcc.exe -mdll -O -Wall -DMS_WIN64 -ID:\MYNAME\AppData\Local\Continuum\Anaconda3\lib\site-packages\numpy\core\include -ID:\MYNAME\AppData\Local\Continuum\Anaconda3\include-ID:\MYNAME\AppData\Local\Continuum\Anaconda3\include -c complexFunLib.cpp -o build\temp.win-amd64-3.6\Release\complexfunlib.o In file included from D:\MYNAME\AppData\Local\Continuum\Anaconda3\lib\site-packages\numpy\core\include/numpy/ndarraytypes.h:1809:0, from D:\MYNAME\AppData\Local\Continuum\Anaconda3\lib\site-packages\numpy\core\include/numpy/ndarrayobject.h:18, from D:\MYNAME\AppData\Local\Continuum\Anaconda3\lib\site-packages\numpy\core\include/numpy/arrayobject.h:4, from complexFunLib.cpp:500:
D:\MYNAME\AppData\Local\Continuum\Anaconda3\lib\site-packages\numpy\core\include/numpy/npy_1_7_deprecated_api.h:13:79: note: #pragma message:
D:\MYNAME\AppData\Local\Continuum\Anaconda3\lib\site-packages\numpy\core\include/numpy/npy_1_7_deprecated_api.h(12) : Warning Msg: Using deprecated NumPy API, disable it by #defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
"#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION")
^
complexFunLib.cpp: In function 'PyTypeObject* __Pyx_ImportType(const char*, const char*, size_t, int)':
complexFunLib.cpp:7149:53: warning: unknown conversion type character 'z' in format [-Wformat=]
module_name, class_name, basicsize, size); ^
complexFunLib.cpp:7149:53: warning: unknown conversion type character 'z' in format [-Wformat=]
complexFunLib.cpp:7149:53: warning: too many arguments for format [-Wformat-extra-args]
writing build\temp.win-amd64-3.6\Release\complexFunLib.cp36-win_amd64.def
D:\MYNAME\AppData\Local\Continuum\Anaconda3\Library\mingw-w64\bin\g++.exe -shared -s build\temp.win-amd64-3.6\Release\complexfunlib.o build\temp.win-amd64-3.6\Release\complexFunLib.cp36-win_amd64.def -L. -LD:\MYNAME\AppData\Local\Continuum\Anaconda3\libs -LD:\MYNAME\AppData\Local\Continuum\Anaconda3\PCbuild\amd64 .\complexFunLib.dll -lpython36 -lmsvcr140 -o "D:\MYNAME\PATH_TO_PROJECT\complexFunLib.cp36-win_amd64.pyd"
build\temp.win-amd64-3.6\Release\complexfunlib.o:complexFunLib.cpp:(.text+0x29b5): undefined reference to `mp_mlt_exp_c4'
build\temp.win-amd64-3.6\Release\complexfunlib.o:complexFunLib.cpp:(.text+0x3ba7): undefined reference to `mp_mlt_exp_c8'
collect2.exe: error: ld returned 1 exit status error: command 'D:\MYNAME\AppData\Local\Continuum\Anaconda3\Library\mingw-w64\bin\g++.exe' failed with exit status 1
And when I run (to try just in case) python setup.py --build_ext --inplace --compiler=msvc
since I don't know if it should be compiled also with the same compiler that compiled the DLL, it uses Visual Studio's compiler and raises this error:
EDIT, I PUT THE FULL LOG FOR MSVC:
running build_ext
cythoning complexFunLib.pyx to complexFunLib.cpp
building 'complexFunLib' extension
creating build
creating build\temp.win-amd64-3.6
creating build\temp.win-amd64-3.6\Release
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -ID:\MYNAME\AppData\Local\Continuum\Anaconda3\lib\site-packages\numpy\core\include -ID:\MYNAME\AppData\Local\Continuum\Anaconda3\include -ID:\MYNAME\AppData\Local\Continuum\Anaconda3\include "-IC:\ProgramFiles (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\8.1\include\shared" "-IC:\Program Files (x86)\Windows Kits\8.1\include\um" "-IC:\Program Files (x86)\Windows Kits\8.1\include\winrt" /EHsc /TpcomplexFunLib.cpp /Fobuild\temp.win-amd64-3.6\Release\complexFunLib.obj
complexFunLib.cpp
d:\MYNAME\appdata\local\continuum\anaconda3\lib\site-packages\numpy\core\include\numpy\npy_1_7_deprecated_api.h(12) : Warning Msg: Using deprecated NumPy API, disable it by #defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:. /LIBPATH:D:\MYNAME\AppData\Local\Continuum\Anaconda3\libs /LIBPATH:D:\MYNAME\AppData\Local\Continuum\Anaconda3\PCbuild\amd64 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\amd64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.10240.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\8.1\lib\winv6.3\um\x64" .\complexFunLib.lib /EXPORT:PyInit_complexFunLib build\temp.win-amd64-3.6\Release\complexFunLib.obj "/OUT:D:\MYNAME\PATH_TO_PROJECT\complexFunLib.cp36-win_amd64.pyd" /IMPLIB:build\temp.win-amd64-3.6\Release\complexFunLib.cp36-win_amd64.lib complexFunLib.obj : warning LNK4197: export 'PyInit_complexFunLib' specified multiple times; using first specification
Creating library build\temp.win-amd64-3.6\Release\complexFunLib.cp36-win_amd64.lib and object build\temp.win-amd64-3.6\Release\complexFunLib.cp36-win_amd64.exp
complexFunLib.obj : error LNK2001: unresolved external symbol mp_mlt_exp_c8
complexFunLib.obj : error LNK2001: unresolved external symbol mp_mlt_exp_c4
D:\PATH_TO_PROJECT\complexFunLib.cp36-win_amd64.pyd : fatal error LNK1120: 2 unresolved externals
error: command 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\link.exe' failed with exit status 1120
These two errors are, I believe, the same, and the 'undefined references' or 'external symbols' mp_mlt_exp_c4
and mp_mlt_exp_c8
are functions declared and defined in the C++ header and .cpp, and also in the .pxd and .pyx, as can be seen from the tutorial page I linked at the beginning.
I'm really unsure how to resolve this, it looks like a linking problem with Cython machinery, so if anyone knowledgeable in that area has a solution, I'd be glad to hear it :).
EDIT:
The dumpbin
asked by @ead:
Dump of file complexFunLib.dll
File Type: DLL
Section contains the following exports for complexFunLib.dll
00000000 characteristics 5B1800BA time date stamp Wed Jun 6 17:41:46 2018 0.00 version 1 ordinal base 2 number of functions 2 number of names ordinal hint RVA name 1 0 00001000 mp_mlt_exp_c4 = _mp_mlt_exp_c4 2 1 000010E0 mp_mlt_exp_c8 = _mp_mlt_exp_c8
Summary
1000 .data 1000 .gfids 1000 .rdata 1000 .reloc 1000 .rsrc 1000 .text