当我使用opencv的API cvLoadImage(const char *filename, int iscolor)
时,它接受const char *
作为文件名。当文件名不是ASCII字符时,我试图将其转换为UTF8字符串。它失败是因为fopen()
中调用的cvLoadImage()
无法将文件名的字符解释为ASCII字符串。如果尝试打开文件名,我可能会使用_wfopen()
,但如果在第三方库中调用fopen()
,是否有任何方法可以解决此问题?
谢谢。
答案 0 :(得分:9)
使用GetShortPathName。它将返回该文件的旧名称(8.3),您应该能够将其转换为char*
,因为它不应包含任何非ASCII字符。
我刚刚用一些语言特定的字符对其进行了测试,它按照我的描述工作。我已经使用fopen从C:\łęłęł\ąóąóą.tsttgbb
成功打开了一个文件。
答案 1 :(得分:1)
cvLoadImage
(这是合理的,你不想搞砸了),你可以尝试欺骗它。
CreateSymbolicLink
创建指向该文件的链接。不过,我不确定它是否可行,因为MKLINK
命令行实用程序需要管理权限。我会选择选项1或2,但更简单。
答案 2 :(得分:0)
这是对这个问题的后期贡献。我查看了运行时库的源代码(微软提供的),发现我可以替换fopen使用的例程,用以下代码映射ANSI字符串(只需将它链接到你的exe中,它将替换它中的例程)运行时库)。
列出的版本适用于使用v141_xp工具包的Visual Studio 2017。我还没有为其他版本测试它,但我想可能需要一些小的改动(比如例程本身的名称)。如果违规库是DLL,它当然不会起作用。按照你的意愿做好准备。
#ifdef _DEBUG
#define _NORMAL_BLOCK 1
#define _CRT_BLOCK 2
#define _malloc_crt(s) (_malloc_dbg (s, _CRT_BLOCK, __FILE__, __LINE__))
#else
#define _malloc_crt _malloc_base
#endif
// A hack to make fopen et al accept UTF8 strings (as at Visual Studio 2017), see:
// D:\Program Files (x86)\Windows Kits\10\Source\10.0.10240.0\ucrt\internal\string_utilities.cpp
// D:\Program Files (x86)\Windows Kits\10\Source\10.0.10240.0\ucrt\inc\corecrt_internal_traits.h
extern "C" BOOL __cdecl __acrt_copy_path_to_wide_string (char const* const path, wchar_t** const result)
{
#if _MSC_VER != 1910
#define STRINGIZE_HELPER(x) #x
#define STRINGIZE(x) STRINGIZE_HELPER(x)
__pragma (message (__FILE__ "(" STRINGIZE (__LINE__) ") : Error: Code not tested for this version of Visual Studio"));
#endif
assert (path);
assert (result);
// Compute the required size of the wide character buffer:
int length = MultiByteToWideChar (CP_UTF8, 0, path, -1, nullptr, 0);
assert (length > 0);
*result = (wchar_t *) _malloc_crt (T2B (length));
// Do the conversion:
length = MultiByteToWideChar (CP_UTF8, 0, path, -1, *result, length);
assert (length);
return TRUE;
}
答案 3 :(得分:0)
setlocale(LC_ALL, ".65001");
fopen(u8"中文路径.txt", "rb"); //window7(中文) vs2017 ok