【问题标题】:OpenCV : io_win32.cc : _wfopen has not been declared MinGWOpenCV:io_win32.cc:_wfopen 尚未声明 MinGW
【发布时间】:2018-09-23 19:04:43
【问题描述】:

我正在尝试使用 TDM MinGW (5.1.0) 以及 code blocks (32 bit)CMake 从源代码构建 OpenCV,同时运行 mingw32-make 我收到 io_win32.cc : _wfopen has not been declared 错误。

[  0%] Built target gen-pkgconfig
[  2%] Built target zlib
[  5%] Built target libjpeg-turbo
[  7%] Built target libtiff
[ 15%] Built target libwebp
[ 18%] Built target libjasper
[ 19%] Built target libpng
[ 24%] Built target IlmImf
[ 24%] Building CXX object 3rdparty/protobuf/CMakeFiles/libprotobuf.dir/src/google/protobuf/stubs/io_win32.cc.obj
D:\Programs\OpenCV-Source\opencv\3rdparty\protobuf\src\google\protobuf\stubs\io_win32.cc: In function 'FILE* google::protobuf::internal::win32::fopen(const char*, const char*)':
D:\Programs\OpenCV-Source\opencv\3rdparty\protobuf\src\google\protobuf\stubs\io_win32.cc:330:10: error: '::_wfopen' has not been declared
   return ::_wfopen(wpath.c_str(), wmode.c_str());
          ^
3rdparty\protobuf\CMakeFiles\libprotobuf.dir\build.make:258: recipe for target '3rdparty/protobuf/CMakeFiles/libprotobuf.dir/src/google/protobuf/stubs/io_win32.cc.obj' failed
mingw32-make[2]: *** [3rdparty/protobuf/CMakeFiles/libprotobuf.dir/src/google/protobuf/stubs/io_win32.cc.obj] Error 1
CMakeFiles\Makefile2:715: recipe for target '3rdparty/protobuf/CMakeFiles/libprotobuf.dir/all' failed
mingw32-make[1]: *** [3rdparty/protobuf/CMakeFiles/libprotobuf.dir/all] Error 2
Makefile:161: recipe for target 'all' failed
mingw32-make: *** [all] Error 2

谷歌搜索了一段时间后,我发现this link 指出wfopen 是在wchar.h 下定义的

#ifdef __MSVCRT__
_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW fgetws (wchar_t*, int, FILE*);
_CRTIMP int __cdecl __MINGW_NOTHROW fputws (const wchar_t*, FILE*);
_CRTIMP wint_t __cdecl __MINGW_NOTHROW  getwc (FILE*);
_CRTIMP wint_t __cdecl __MINGW_NOTHROW  getwchar (void);
_CRTIMP wint_t __cdecl __MINGW_NOTHROW  putwc (wint_t, FILE*);
_CRTIMP wint_t __cdecl __MINGW_NOTHROW  putwchar (wint_t);
#ifndef __STRICT_ANSI__
_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW _getws (wchar_t*);
_CRTIMP int __cdecl __MINGW_NOTHROW _putws (const wchar_t*);
_CRTIMP FILE* __cdecl __MINGW_NOTHROW   _wfdopen(int, const wchar_t *);
_CRTIMP FILE* __cdecl __MINGW_NOTHROW   _wfopen (const wchar_t*, const wchar_t*);
_CRTIMP FILE* __cdecl __MINGW_NOTHROW   _wfreopen (const wchar_t*, const wchar_t*, FILE*);
_CRTIMP FILE* __cdecl __MINGW_NOTHROW   _wfsopen (const wchar_t*, const wchar_t*, int);
_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW _wtmpnam (wchar_t*);
_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW _wtempnam (const wchar_t*, const wchar_t*);
_CRTIMP int __cdecl __MINGW_NOTHROW _wrename (const wchar_t*, const wchar_t*);
_CRTIMP int __cdecl __MINGW_NOTHROW _wremove (const wchar_t*);
_CRTIMP void __cdecl __MINGW_NOTHROW    _wperror (const wchar_t*);
_CRTIMP FILE* __cdecl __MINGW_NOTHROW   _wpopen (const wchar_t*, const wchar_t*);
#endif  /* __STRICT_ANSI__ */
#endif  /* __MSVCRT__ */

我不确定如何以及在何处添加他们在链接中讨论的 -U__STRICT_ANSI__ 选项。 无论如何,谁能帮我解决这个问题?任何帮助将不胜感激。

【问题讨论】:

  • "如何以及在何处添加 -U__STRICT_ANSI__ 选项" - 打开(在任何文本编辑器中)文件 CMakeCache.txt,位于构建目录中,找到 CMAKE_CXX_FLAGS 变量并将给定选项添加到其价值。然后重新运行cmakemingw32-make。这种方式可能不会产生预期的效果(例如,如果该选项将被CMakeLists.txt脚本中的选项取消。但如果它有效,那么它比修改系统标题更好。
  • @Tsyvarev 谢谢,我想你是对的,如果我把那个标志放在 CMAKE_CXX_FLAGS 中,那么它就可以工作。使用我的方法很麻烦,因为许多方法都不是 ANSI,之后我遇到了很多错误和警告。

标签: c++ opencv cmake mingw


【解决方案1】:

我不知道我怎么可能让它变得更简单,我因为没有简化它而被否决了。
无论如何,在wchar.h 中,如果我通过删除#ifndef __STRICT_ANSI__ 来放置#ifdef __STRICT_ANSI__,它会完美运行。我不知道这是否是正确的做法,但它确实有效!

更新

上述方法确实有效,但由于在 opencv 源文件中使用了很多非 ANSI 方法,编译器每次遇到此类方法时都会开始抱怨。因此,最好在我们正在构建源代码的CMakeCache.txt 中设置CMAKE_CXX_FLAGS:STRING=-U__STRICT_ANSI__ 标志。这种方式更合适也更省事。

【讨论】:

    【解决方案2】:

    我也在构建 OpenCV 并且遇到了同样的问题。首先我看一下文件io_win32.cc:

    FILE* fopen(const char* path, const char* mode) {
    #ifdef SUPPORT_LONGPATHS
      if (null_or_empty(path)) {
        errno = EINVAL;
        return NULL;
      }
      wstring wpath;
      if (!as_windows_path(path, &wpath)) {
        errno = ENOENT;
        return NULL;
      }
      wstring wmode;
      if (!strings::utf8_to_wcs(mode, &wmode)) {
        errno = EINVAL;
        return NULL;
      }
      return ::_wfopen(wpath.c_str(), wmode.c_str()); //the error
    #else
      return ::fopen(path, mode);
    #endif
    }
    

    似乎可以通过在同一个文件 io_win32.cc 中禁用 SUPPORT_LONGPATHS 来使用 fopen 代替 _wfopen:

    // Comment this out to fall back to using the ANSI versions (open, mkdir, ...)
    // instead of the Unicode ones (_wopen, _wmkdir, ...). Doing so can be useful to
    // debug failing tests if that's caused by the long path support.
    #define SUPPORT_LONGPATHS
    

    如果您对 SUPPORT_LONGPATHS 感到好奇:https://www.itprotoday.com/windows-10/enable-long-file-name-support-windows-10。基本上,它支持长达 32,767 个字符的长文件名。

    【讨论】:

      猜你喜欢
      • 2012-01-25
      • 2011-01-22
      • 2017-05-18
      • 2017-07-05
      • 2019-09-19
      • 2012-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多