c++hextostring不能显示中文_Mathematica CCompilerDriver的两个中文编码问题

92efe711b9af5ef7b6e3fdc0f643f8f7.png

为了加速Mathematica程序,可以使用Compile[]为变量指定机器类型,得到一个高效运行的函数。Compile有一个选项CompilationTarget,默认值"WVM",可选"C"。"WVM"生成Wolfram虚拟机代码,"C"使用一个外部C编译器,生成native机器代码。

在我使用CompilationTarget->"C"时,定位了两处中文编码问题,网络上还未见讨论过,这篇文章是为了给以后遇到同样问题的人提供一个参考。如果你不希望了解我定位这些问题的过程,请直接跳到第11节查看解决方案。

1、在Windows平台上,CCompilerDriver包会自动寻找你的:

  • Cygwin gcc
  • MinGW
  • MSVC
  • Intel C Compiler

四种C编译器。实现代码在

...Wolfram ResearchMathematica11.3SystemFilesComponentsCCompilerDriver

里面。

d5e57db45b501e2817dac2ae8abfaeda.png
CCompilerDriver的内容

2、CCompilerDriver在我的机器上没有找到上述任何一个C编译器,这是因为:

我刚好删除了Cygwin(因为有了WSL),也没有安装Intel C Compiler.

文档中说MinGW 5.1.8通过了测试,而我安装的6.3.0.

文档中说VS2010 VS2012通过了测试,而我安装的VS2017.

3、我发现在我的二奶机上,CCompilerDriver找到了VS2017里面的MSVC,然后我发现:

VisualStudioCompiler.m的11.3版本会查找VS2017,而11.0不支持。

4、我将主力机上的Mathematica更新到11.3版本,它仍然不能找到MSVC,我运行了VisualStudioCompiler.m,它给出这些错误信息:

a9bcdf7a337ff0640b427668d9866bb7.png
运行VisualStudioCompiler[“ResolveInstallation”][Automatic]

5、我阅读了VisualStudioCompiler.m,它使用MS提供的vswhere.exe查找所有安装的VS,大概是这样:

$vswherePath = FileNameJoin[{$InstallationDirectory, "SystemFiles",
    "Components", "CCompilerDriver", "Resources", "Windows", "vswhere.exe"}]
$vswhereOutput = Import["!"<>QuoteFile[$vswherePath]<>" -products * -legacy -format json", "Text"]
$vsInfo := $vsInfo = If[$vswhereWorks, ImportString[$vswhereOutput, "RawJSON"], False]

vswhere的输出中,"description"的值是一串中文,所以ImportString的JSON Parser挂了。

6、解决这个问题:

尝试在调用Compile[]之前,对$CCompiler赋值以显式指定MSVC的安装位置,参考CCompilerDriver User Guide的Specific Compilers章节。这似乎行不通因为CreateLibrary只接受CCompilers[Full]里面列出的经过注册编译器,所以如果CCompilerDriver没有自动检测到编译器,指定它也没有用。

1)或安装英文版VS2017。如果已经安装了中文版VS2017,使用VS Installer将VS的语言包换成英文不能改变vswhere的输出,使用英文版VS Installer重装VS才可以。

2)或重写VisualStudioCompiler.m。它只使用了vswhere给出的installationPath和installationVersion键的值,所以调用vswhere时使用 -property "xxx" 参数,两次分别获取这两个值( -property 一次只能指定一个键),而不让它输出description就可以避免吃到中文字符。

3)或自己写一个假的vswhere替换掉CCompilerDriverResourcesWindowsvswhere.exe,直接给出你的VS安装路径,避免中文编码。

7、使用6、(1)继续,Compile[]报告这个错误:

b8442e3ff64f4479d9ad2e7d07e873b9.png

嗯,显然又是一个中文编码问题。

8、找一下CreateLibrary[]在哪里,没有收获。查找"BuildFolder"串,在CCompilerDriver.m中找到:

$CCompilerInternalDirectory = 
    FileNameJoin[{Quiet[ApplicationDataUserDirectory["CCompilerDriver"]], 
    "BuildFolder", $MachineName<>"-"<>ToString[$ProcessID]}]

$MachineName显然是罪魁祸首,因为我的计算机名字是一串中文。

9、将计算机名改成英文,Compile[ , ,CompilationTarget -> "C"]现在可以工作了。

b6b70a29709cb7aeb8ffbdc65d25c078.png

10、新的发现

今天我出门带了二奶机,我发现即使vswhere给出中文输出,CCompiler仍能识别到MSVC。

有这几个观察:

  • 二奶机一开始就使用英文站点下载的VS Installer安装了VS2017,仅有简中语言包
  • 二奶机上vswhere根据系统显示语言正确地给出中文或英文输出,且CCompilerDriver总是可以找到MSVC
  • 使用中文站点下载的VS Installer安装VS后,主力机上的vswhere总是给出中文输出(而与系统显示语言无关),且CCompilerDriver总是找不到MSVC

我认为,中文站点的中文版VS Installer在机器上注册的信息存在兼容性问题,而英文版VS Installer正确提供了多语言注册信息,且CCompilerDriver遇到的编码问题就是中文版VS Installer造成的。这与VS的语言包和系统语言无关。

11、总结

如果你的Mathematica 11.3以上版本无法识别已安装的VS 2017中的MSVC,检查你是否使用了从中文站点下载的中文版VS Installer。如果是,尝试将VS Installer换成英文版,或者删除VS和VS Installer后用英文版VS Installer重装VS。VS的语言包和系统显示语言都可以是中文。

如果你使用Compile[]时报告编译错误,编译器无法打开工作目录,且工作目录中出现了乱码,检查你的计算机名字是否是中文,将中文换为仅英文。Compile[]使用你的计算机名字和计算机名字+进程ID来为每个机器的每个进程生成唯一确定的工作目录,而中文计算机名会在这一步导致编码问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值