Ошибки компиляции с CImg

Я использую библиотеку CImg впервые и получаю ошибки компиляции с простой тестовой программой, которая включает только CImg.h. Почему это? Как я могу это исправить?

Код программы:

#include "../headers/CImg.h"
using namespace cimg_library;
int main()
{
    return 0;
}

Ошибки компиляции:

In function 'FILE* cimg_library::cimg::fopen(const char*, const char*)':
5065|error: '_fileno' was not declared in this scope
In function 'int cimg_library::cimg::fseek(FILE*, INT_PTR, int)':
5093|error: '_fseeki64' was not declared in this scope
In function 'INT_PTR cimg_library::cimg::ftell(FILE*)':
5102|error: '_ftelli64' was not declared in this scope

Это было сделано на ПК с 64-битной Windows 8.1.

Команда:

g++.exe -Wall -fexceptions -g -std=c++11  -c "D:\informatics\Projects\image experiments\Rectangle to circle stretcher\sources\main.cpp" -o obj\Debug\sources\main.o

Я пробовал это без части -std=c++11, и я получаю 2 ошибки вместо 3. Я не получаю 5065|error: '_fileno' was not declared in this scope. То же самое произойдет, если я заменю его на -std=gnu++11

Я также попробовал это на своем ноутбуке, на котором установлена ​​64-битная версия Windows 7, и там происходит то же самое.

Пока у меня есть обходной путь для первой ошибки, но ничего для двух других.


person indjev99    schedule 15.07.2016    source источник
comment
Как вы пытались его скомпилировать - какая у вас была команда? На какой платформе вы находитесь?   -  person Mark Setchell    schedule 15.07.2016
comment
@Марк Сетчелл Отредактировано.   -  person indjev99    schedule 15.07.2016
comment
Попробуйте добавить #include <stdio.h> в качестве первой строки.   -  person Mark Setchell    schedule 15.07.2016
comment
Нет, не сработало.   -  person indjev99    schedule 15.07.2016
comment
Я не пользуюсь Windows, поэтому я просто предполагаю, что использую комментарии, а не отвечаю, но, возможно, мы доберемся таким образом. Попробуйте добавить #include <cstdio> в качестве первой строки. Попробуйте добавить некоторые или все из них в команду компиляции -Dcimg_display=0 в начале и/или -lgdi32 в конце.   -  person Mark Setchell    schedule 15.07.2016
comment
Не уверен, как вы установили g++, но вам, вероятно, нужно сообщить компилятору, где находятся заголовочные файлы (т.е. включаемые файлы). Вероятно, вам нужно добавить -I /path/to/includes и -L /path/to/libs в команду компиляции, чтобы она могла найти заголовочные файлы - не только CImg, но и системные стандартные заголовочные файлы C++.   -  person Mark Setchell    schedule 15.07.2016
comment
#include ‹cstdio›, -Dcimg_display=0 и -lgdi32 не работали. И я не уверен, что вы имеете в виду в последнем комментарии. Я никогда не делал таких вещей раньше, и это сработало. Если это имеет значение, я использую Code::Blocks.   -  person indjev99    schedule 15.07.2016
comment
Хорошо, последняя попытка. Попробуйте изменить -std=c++11 на -std=gnu++11   -  person Mark Setchell    schedule 16.07.2016
comment
Все те же ошибки. Есть ли какой-нибудь учебник, который показывает все, включая настройку библиотеки и тому подобное? Я собираюсь попробовать это на моем другом компьютере, чтобы посмотреть, что там происходит. Тогда выложу обновление.   -  person indjev99    schedule 16.07.2016
comment
Я в замешательстве, вы сказали, что используете команду g++, а теперь говорите, что используете Code::Blocks. Можете ли вы попробовать команду g++, которую, как вы сказали, использовали только в командной строке вне Code::Blocks, чтобы мы могли исключить любые эффекты Code::Blocks? Кроме того, с -std=gnu++11.   -  person Mark Setchell    schedule 17.07.2016
comment
@Mark Setchell Я хотел сказать, что сначала использовал Code :: Blocks. Но после того, как я получил ошибки, я начал делать все в командной строке и все равно получил те же ошибки.   -  person indjev99    schedule 17.07.2016
comment
@Mark Setchell Я попробовал еще раз с '-std=gnu++11', и оказалось, что я пропустил тот факт, что первая ошибка исчезла.   -  person indjev99    schedule 18.07.2016
comment
Можете ли вы скомпилировать первый приведенный здесь пример кода мизинца/пурпура? Ничего общего с CImg. cs.technion.ac. il/users/yechiel/c++-faq/ Я все еще думаю, что проблема в том, что ваш компилятор не может найти заголовочный файл cstdio.   -  person Mark Setchell    schedule 18.07.2016
comment
@Mark Setchell Да, я могу даже с '-std=c++11'. Я читал о первой ошибке, и, похоже, это какая-то ошибка с cstdio, и обходной путь заключается в использовании '-std=gnu++11'. github.com/dtschump/CImg/issues/43 Однако я не видел две другие ошибки упоминаются где угодно.   -  person indjev99    schedule 18.07.2016


Ответы (1)


В случае CodeBlock 16.01 stdio.h содержит строки

#if __MSVCRT_VERSION__ >= 0x800
_CRTIMP int __cdecl __MINGW_NOTHROW     _fseek_nolock (FILE*, long, int);
_CRTIMP long __cdecl __MINGW_NOTHROW    _ftell_nolock (FILE*);

_CRTIMP int __cdecl __MINGW_NOTHROW     _fseeki64 (FILE*, __int64, int);
_CRTIMP __int64 __cdecl __MINGW_NOTHROW _ftelli64 (FILE*);
_CRTIMP int __cdecl __MINGW_NOTHROW     _fseeki64_nolock (FILE*, __int64, int);
_CRTIMP __int64 __cdecl __MINGW_NOTHROW _ftelli64_nolock (FILE*);
#endif

т. е. эти функции не объявлены, если __MSVCRT_VERSION__ не меньше 0x800. Следующее может сработать (по крайней мере, для CodeBlocks 16.01)

#if defined(__MINGW32__)
#define __MSVCRT_VERSION__ 0x800
#define _WIN32_WINNT 0x0500
#endif

// if needed
// #define _fileno fileno

#include "CImg.h"

Если stdio.h не содержит объявлений для _fseeki64 и других, либо

  • Используйте CImg 1.6.9, который не использует _fseeki64,
  • обновить gcc/g++ или
  • предоставить собственную реализацию для _fseeki64 (если такую ​​можно где-то найти).
person J.J. Hakala    schedule 18.07.2016
comment
Я просто хочу отметить, что я использую не компилятор по умолчанию, который поставляется с Code::Blocks, а 64-битную версию MinGW, так что я должен изменить какую-либо часть этого? (Я попробовал это и со стандартным, и я получаю те же ошибки.) - person indjev99; 19.07.2016
comment
@indjev99 indjev99 Вероятно, вам следует отредактировать свой вопрос, включив в него конкретные сведения о вашей среде разработки. Если в файле stdio.h нет объявления для _fseeki64, может работать более ранняя версия CImg (1.6.9), поскольку она не вызывает _fseeki64. - person J.J. Hakala; 19.07.2016
comment
@ indjev99 indjev99 Я действительно протестировал свое решение с 64-битной версией g++ v5.4.0 (среда msys2), и компиляция сработала. - person J.J. Hakala; 19.07.2016
comment
Большое спасибо, это сработало. Я понимаю, для чего нужна строка #define __MSVCRT_VERSION__ 0x800, но зачем нам следующая (#define _WIN32_WINNT 0x0500)? Попробовал и без него работает. - person indjev99; 19.07.2016
comment
@ indjev99 Я думаю, что его можно опустить (или, по крайней мере, определить его как 0x502, соответствующий Windows XP SP2 / Server 2003 SP2). Это определение и WINVER могут повлиять на то, какие библиотечные функции и определения будут доступны при компиляции. Использование заголовков Windows - person J.J. Hakala; 19.07.2016