Невозможно преобразовать сгенерированный Cython код языка C в исполняемый файл - PullRequest
0 голосов
/ 05 мая 2019

Я использую операционную систему Windows. У меня есть Visual Studio и все инструменты сборки, связанные с ней. У меня есть простой скрипт на Python. Я использовал Cython для создания файла "C". Я пытаюсь преобразовать этот файл C в исполняемый файл. Я не хочу использовать любые другие модули, такие как pyinstaller, py2exe или cxFreeze.

Преобразование из .py в C прошло успешно. Однако, к сожалению, я получаю некоторые ошибки при преобразовании этого файла C в исполняемый файл.

Может ли кто-нибудь помочь мне? Я проверил различные другие вопросы по этой проблеме, и ни у одного из них нет этой проблемы.

Это мой (скрипт .pyx)

from tkinter import Tk

root = Tk()
root.mainloop()

Я использовал эту следующую команду в CMD для создания расширения C для этого сценария:

python setup.py build_ext --inplace -DMS_WIN64

Затем я использую эту команду в CMD для создания исполняемого файла:

gcc -DMS_WIN64 C:/Users/Siva/Desktop/Scripts/TEST/test.c -IC:/"Program Files"/Python37/include -LC:/"Program Files"/Python37/libs -lpython37 -o output

Это приводит к следующей ошибке:

C:\Users\Siva\Desktop\Scripts\TEST>gcc -DMS_WIN64 C:/Users/Siva/Desktop/Scripts/TEST/test.c -IC:/"Program Files"/Python37/include -LC:/"Program Files"/Python37/libs -lpython37.a -o output
C:/Users/Siva/Desktop/Scripts/TEST/test.c:213:41: warning: division by zero [-Wdiv-by-zero]
     enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) };
                                         ^
C:/Users/Siva/Desktop/Scripts/TEST/test.c:213:12: error: enumerator value for '__pyx_check_sizeof_voidp' is not an integer constant
     enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) };
            ^~~~~~~~~~~~~~~~~~~~~~~~

Я приложил скриншот ошибки ниже

введите описание изображения здесь

Ответы [ 2 ]

1 голос
/ 08 мая 2019

Наконец, после долгой вечной борьбы я нашел решение.Спасибо Джошуа за большую поддержку.

В коде .PYX есть небольшая модификация.Похоже, что мы должны определить все внутри функции, чтобы при преобразовании кода в язык C в нем была основная функция.

Итак, первый шаг - это .PYX, отредактированный как:

from tkinter import Tk

cdef public void function():
    root = Tk()
    root.mainloop()

if __name__ == "__main__":
    function()

Затем я использовал следующую команду для генерации файла заголовка (.h) и программный файл C

python -m cython test.pyx --embed

Это хитрость:

Перейдите к созданному программному файлу C и найдитефункцию wmain и удалите из нее "w".Или вы можете просто нажать Ctrl + F для поиска wmain и заменить его экземпляры на main.

Например, в моей программе был только один экземпляр wmain.Я изменил это на главное.Это похоже на код, показанный ниже.Просто измените wmain на main.

#if PY_MAJOR_VERSION < 3
int main(int argc, char** argv) {
#elif defined(WIN32) || defined(MS_WINDOWS)
int wmain(int argc, wchar_t **argv) 

Затем я использовал команду GCC для генерации исполняемого файла.Команда выглядит следующим образом.Я не понимаю, почему это работает.Но это так.

x86_64-w64-mingw32-gcc-8.1.0 -mconsole -DSIZEOF_VOID_P=8 -DMS_WIN64 C:/Users/Siva/Desktop/Scripts/CYTHON/test.c -IC:/"Program Files"/Python37/include -LC:/"Program Files"/Python37/libs -lpython37 -o output

Я только хотел бы, чтобы кто-нибудь объяснил, почему подход работает.

0 голосов
/ 06 мая 2019

Экологическая проверка не пройдена; возможно автоопределение не работает. Попробуйте одно из следующих, чтобы переопределить его:

gcc -DSIZEOF_VOID_P=8 -DMS_WIN64 ...

gcc -DSIZEOF_VOID_P=4 ...

Где константа 8 для 64-битного выхода, а константа 4 для 32-битного выхода. Скорее всего, вы настроили 64-битную версию и фактически вызвали 32-битную версию gcc. Если это так, следующий вызов должен работать при условии, что также установлен 64-битный таргетинг gcc.

x86_64-w64-mingw32-gcc -DSIZEOF_VOID_P=8 -DMS_WIN64 ...
...