I am using CFFI to automatically wrap a DLL using the API - out of line approach.
This is actually done via Continuous Integration and has worked well so far. To make this possible, the DLL header file is preprocessed in Visual Studio and the output of which is used in the call to FFI.cdef
.
Our DLL has recently gotten more complex with the inclusion of complex.h
which results a few difficulties.
One issue I'm having now is that CFFI doesn't seem to like duplicate function definitions.
I am getting this error: cffi.error.FFIError: multiple declarations of function cimag
.
When I look into the preprocessed header file, I can indeed see duplicates of this declaration:
double __cdecl cimag( _Dcomplex _Z);
Note that this is simply a redeclaration of the same function with the same signature. The duplicates seem to be added as part of the preprocessing step. This is perfectly legal C though and compiles without issue.
What can I do to make CFFI happy with this?
I am already postprocessing the preprocessed header file to handle microsoft specific additions such as:
declspec(noreturn)
(just deleting these occurrences)__w64
(just deleting these occurrences)__int64
(Adding typedef for int64_t
Update
After taking a quick look at the source code for CFFI around where the exception was raised from, I discovered a keyword: override
which can be provided to ffi.cdef
. Adding override=True
allows the wrapping process to progress but I now get a syntax error in the autogenerated wrapper C file :
(pywrapper) c:\projects\wrapper_proj\pywrapper>python -m release_process.cffi_wrap_dll -h
generating .\pywrapper\dll_wrapper\_command.c
(already up-to-date)
the current directory is 'c:\\projects\\wrapper_proj\\pywrapper'
running build_ext
building 'pywrapper.dll_wrapper._command' extension
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -Ic:\projects\wrapper_proj\pywrapper\pywrapper\dll_wrapper -IC:\Users\user\python_envs\pywrapper\include -IC:\Python37-32\include -IC:\Python37-32\include "-IC:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE" "-IC:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ATLMFC\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" "-IC:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE" "-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" /Tcpywrapper\dll_wrapper\_command.c /Fo.\Release\pywrapper\dll_wrapper\_command.obj
_command.c
pywrapper\dll_wrapper\_command.c(11262): error C2143: syntax error: missing ')' before '*'
pywrapper\dll_wrapper\_command.c(11262): error C2143: syntax error: missing '{' before '*'
pywrapper\dll_wrapper\_command.c(11262): error C2059: syntax error: ')'
pywrapper\dll_wrapper\_command.c(11263): error C2054: expected '(' to follow 'p'
pywrapper\dll_wrapper\_command.c(11269): error C2061: syntax error: identifier '_locale_tstruct'
pywrapper\dll_wrapper\_command.c(11269): error C2059: syntax error: '}'
pywrapper\dll_wrapper\_command.c(11272): error C2143: syntax error: missing ')' before '*'
pywrapper\dll_wrapper\_command.c(11272): error C2143: syntax error: missing '{' before '*'
pywrapper\dll_wrapper\_command.c(11272): error C2059: syntax error: ')'
pywrapper\dll_wrapper\_command.c(11273): error C2054: expected '(' to follow 'p'
pywrapper\dll_wrapper\_command.c(11281): error C2061: syntax error: identifier 'locrefcount'
pywrapper\dll_wrapper\_command.c(11281): error C2059: syntax error: '}'
pywrapper\dll_wrapper\_command.c(11284): error C2143: syntax error: missing ')' before '*'
pywrapper\dll_wrapper\_command.c(11284): error C2143: syntax error: missing '{' before '*'
pywrapper\dll_wrapper\_command.c(11284): error C2059: syntax error: ')'
pywrapper\dll_wrapper\_command.c(11285): error C2054: expected '(' to follow 'p'
pywrapper\dll_wrapper\_command.c(11307): error C2061: syntax error: identifier 'threadlocinfo'
pywrapper\dll_wrapper\_command.c(11307): error C2059: syntax error: '}'
pywrapper\dll_wrapper\_command.c(11564): error C2065: '_locale_tstruct': undeclared identifier
pywrapper\dll_wrapper\_command.c(11564): error C2059: syntax error: ')'
pywrapper\dll_wrapper\_command.c(11569): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11572): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11575): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11578): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11581): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11584): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11587): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11590): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11593): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11596): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11599): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11602): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11605): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11608): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11611): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11614): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11617): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11620): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11623): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11626): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11629): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11632): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11635): error C2059: syntax error: ','
pywrapper\dll_wrapper\_command.c(11650): error C2065: '_locale_tstruct': undeclared identifier
pywrapper\dll_wrapper\_command.c(11650): error C2037: left of 'y' specifies undefined struct/union '_cffi_align___locale_tstruct'
pywrapper\dll_wrapper\_command.c(11652): error C2065: 'locrefcount': undeclared identifier
pywrapper\dll_wrapper\_command.c(11652): error C2037: left of 'y' specifies undefined struct/union '_cffi_align__locrefcount'
pywrapper\dll_wrapper\_command.c(11654): error C2065: 'threadlocinfo': undeclared identifier
pywrapper\dll_wrapper\_command.c(11654): error C2037: left of 'y' specifies undefined struct/union '_cffi_align__threadlocinfo'
pywrapper\dll_wrapper\_command.c(11649): fatal error C1903: unable to recover from previous error(s); stopping compilation
Internal Compiler Error in C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\cl.exe. You will be prompted to send an error report to Microsoft later.
INTERNAL COMPILER ERROR in 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\cl.exe'
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more information
Traceback (most recent call last):
File "C:\Python37-32\lib\distutils\_msvccompiler.py", line 423, in compile
self.spawn(args)
File "C:\Python37-32\lib\distutils\_msvccompiler.py", line 542, in spawn
return super().spawn(cmd)
File "C:\Python37-32\lib\distutils\ccompiler.py", line 909, in spawn
spawn(cmd, dry_run=self.dry_run)
File "C:\Python37-32\lib\distutils\spawn.py", line 38, in spawn
_spawn_nt(cmd, search_path, dry_run=dry_run)
File "C:\Python37-32\lib\distutils\spawn.py", line 81, in _spawn_nt
"command %r failed with exit status %d" % (cmd, rc))
distutils.errors.DistutilsExecError: command 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\cl.exe' failed with exit status 2
During handling of the above exception, another exception occurred:
I can see in the preprocessed header file a definition for locale_t
:
typedef struct __crt_locale_data_public
{
unsigned short const* _locale_pctype;
int _locale_mb_cur_max;
unsigned int _locale_lc_codepage;
} __crt_locale_data_public;
typedef struct __crt_locale_pointers
{
struct __crt_locale_data* locinfo;
struct __crt_multibyte_data* mbcinfo;
} __crt_locale_pointers;
typedef __crt_locale_pointers* _locale_t;