Я использую CFFI , чтобы автоматически обернуть DLL, используя подход API вне линии.
Это на самом деле делается с помощью непрерывной интеграции и до сих пор хорошо работало. Чтобы сделать это возможным, файл заголовка DLL предварительно обрабатывается в Visual Studio и вывод которого используется при вызове FFI.cdef
.
Наша DLL недавно стала более сложной с включением complex.h
, что приводит к нескольким трудностям.
Одна из проблем, с которыми я сталкиваюсь сейчас, заключается в том, что CFFI, похоже, не нравится повторяющиеся определения функций.
Я получаю эту ошибку: cffi.error.FFIError: multiple declarations of function cimag
.
Когда я просматриваю предварительно обработанный заголовочный файл, я действительно вижу дубликаты этого объявления:
double __cdecl cimag( _Dcomplex _Z);
Обратите внимание, что это просто переопределение одной и той же функции с той же сигнатурой. Дубликаты, кажется, добавляются как часть шага предварительной обработки.
Это вполне допустимый C, но компилируется без проблем.
Что я могу сделать, чтобы CFFI доволен этим?
Я уже выполняю постобработку предварительно обработанного заголовочного файла для обработки специфичных для Microsoft дополнений, таких как:
declspec(noreturn)
(просто удаляя эти вхождения)
__w64
(просто удаляя эти вхождения)
__int64
(Добавление typedef для int64_t
Обновление
После быстрого просмотра исходного кода CFFI о том, откуда возникло исключение, я обнаружил ключевое слово: override
, которое можно указать для ffi.cdef
. Добавление override=True
позволяет процессу переноса выполняться, но теперь я получаю синтаксическую ошибку в автоматически сгенерированном файле оболочки C:
(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:
Я вижу в предварительно обработанном заголовочном файле определение для 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;