Мне приходится использовать чужие заголовочные файлы C, которые содержат пустые структуры. У меня нет контроля над этими заголовками, иначе я бы изменил их, поскольку пустые структуры не являются обычными C. Структуры выдают ошибки C2016, как и ожидалось от стандартного компилятора в Visual Studio Code (в Windows). Первоначальный автор заголовков использует какой-то другой компилятор, который допускает пустые структуры.
Вот пример ошибки, которую я получаю:
message_definitions.h(45): error C2016: C requires that a struct or union have at least one member
Вот пример структур:
typedef struct {
} Controller_Do_Graceful_Shutdown_t;
Согласно тому, что я прочитал, вам разрешено использовать пустые структуры, используя другие компиляторы, такие как gcc. Я установил gcc и проверил его существование:
gcc -v
Using built-in specs.
COLLECT_GCC=C:\msys64\ucrt64\bin\gcc.exe
COLLECT_LTO_WRAPPER=C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../gcc-13.2.0/configure --prefix=/ucrt64 --with-local-prefix=/ucrt64/local --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --with-native-system-header-dir=/ucrt64/include --libexecdir=/ucrt64/lib --enable-bootstrap --enable-checking=release --with-arch=nocona --with-tune=generic --enable-languages=c,lto,c++,fortran,ada,objc,obj-c++,jit --enable-shared --enable-static --enable-libatomic --enable-threads=posix --enable-graphite --enable-fully-dynamic-string --enable-libstdcxx-filesystem-ts --enable-libstdcxx-time --disable-libstdcxx-pch --enable-lto --enable-libgomp --disable-libssp --disable-multilib --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-libiconv --with-system-zlib --with-gmp=/ucrt64 --with-mpfr=/ucrt64 --with-mpc=/ucrt64 --with-isl=/ucrt64 --with-pkgversion='Rev3, Built by MSYS2 project' --with-bugurl=https://github.com/msys2/MINGW-packages/issues --with-gnu-as --with-gnu-ld --disable-libstdcxx-debug --with-boot-ldflags=-static-libstdc++ --with-stage1-ldflags=-static-libstdc++
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.2.0 (Rev3, Built by MSYS2 project)
Самая сложная часть
Я использую cffi в Python для «импорта» заголовков C, поэтому используемый компилятор C — это тот, который решит использовать ffibuilder. По умолчанию он использует компилятор Microsoft C, который выдает ошибки C2016. :-(
Вот код cffi:
from cffi import FFI
ffibuilder = FFI()
ffibuilder.set_source("_message_definitions", # name of the output C extension
"""
#include "message_definitions.h"
""",
sources=['message_definitions.c'],
libraries=[])
if __name__ == "__main__":
ffibuilder.compile(verbose=True)
Есть ли способ указать cffi вместо этого использовать gcc или подавить выдаваемые ошибки C2016?
Если бы у меня был контроль над файлами заголовков, я бы сделал именно то, что предлагает ваша ссылка выше. Однако спасибо за ответ!






Visual Studio откажется это компилировать, поскольку она не допускает структуры нулевого размера в C, вместо этого вам нужно использовать gcc для сборки этой библиотеки. если вам необходимо использовать MSVC, вам нужно изменить эти структуры, чтобы они содержали простой char, что и делает gcc, и надеяться, что никто не зависит от их размера в коде.
typedef struct {
char unused;
} some_struct;
чтобы cffi использовать mingw при компиляции, вам необходимо создать файл с именем setup.cfg в той же папке, что и ваш файл cffi Python, со следующим содержимым.
[build]
compiler=mingw32
для этого нет документации, но cffi использует distutils, если этот ответ не удастся в будущем, вы можете проверить историю редактирования этого ответа на предмет сложного способа взлома distutils,
Добавление файла setup.cfg, как было предложено, сработало!
Непроверено... Попробуйте это, если можете... Ответ от 2013 года, который был принят и обработан UV... Если это работает, найдите с помощью поиска
[c] C2016 error on Windows(из вашего заголовка)... Если это работает для вас ...