You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JDK22 Foreign Function & Memory API调用Lammps的Locale问题

JDK 22 Panama调用原生Lammps的Locale数值解析问题

在Ubuntu系统上使用JDK 22的Foreign Function & Memory API(Project Panama)调用原生Lammps程序时,遇到Locale导致的数值解析错误:系统localeconv()->decimal_point为逗号,使得atof函数将字符串2.2598258677677969解析为2。尝试过终端执行export LC_ALL=C、在原生代码中添加#include <clocale>和setlocale(LC_ALL, "C"),均未解决问题。

复现信息

Kotlin调用代码

val l = Linker.nativeLinker()
val d = FunctionDescriptor.of(ValueLayout.JAVA_DOUBLE, ValueLayout.ADDRESS)
val atof = l.downcallHandle(l.defaultLookup().find("atof").get(), d)
val res = atof.invoke(Arena.global().allocateFrom("2.2598258677677969")) as Double
println(res)

原生代码Locale检查

auto a = setlocale(LC_ALL, NULL);
utils::logmesg(this, "old locale {}\n", a);

输出的Locale信息

old locale LC_CTYPE=en_US.UTF-8;LC_NUMERIC=it_IT.UTF-8;LC_TIME=it_IT.UTF-8;LC_COLLATE=en_US.UTF-8;LC_MONETARY=it_IT.UTF-8;LC_MESSAGES=en_US.UTF-8;LC_PAPER=it_IT.UTF-8;LC_NAME=it_IT.UTF-8;LC_ADDRESS=it_IT.UTF-8;LC_TELEPHONE=it_IT.UTF-8;LC_MEASUREMENT=it_IT.UTF-8;LC_IDENTIFICATION=it_IT.UTF-8

系统可用Locale

执行locale -a可见C、C.utf8、POSIX等Locale。

解决方案

1. 单独设置LC_NUMERIC而非LC_ALL

从输出可见LC_NUMERIC仍为it_IT.UTF-8,说明之前的LC_ALL设置未覆盖到该字段。尝试在原生代码中单独设置数值相关Locale,且确保在任何数值解析逻辑之前调用:

#include <clocale>

// 初始化阶段调用
setlocale(LC_NUMERIC, "C");
// 验证设置结果
const char* numLocale = setlocale(LC_NUMERIC, NULL);
printf("Current LC_NUMERIC: %s\n", numLocale);

2. 启动Java程序时强制设置环境变量

如果原生代码设置不生效,可在启动Java程序时直接指定LC_NUMERIC或LC_ALL:

LC_NUMERIC=C java -jar your-application.jar
# 或
LC_ALL=C java -jar your-application.jar

3. 检查Lammps内部Locale逻辑

部分大型原生程序(如Lammps)可能会在内部重置Locale设置,需确认Lammps代码中是否有覆盖Locale的逻辑,如有需调整其执行顺序或关闭该逻辑。

4. 验证字符串编码传递

确保Panama传递的字符串编码符合原生函数预期,可明确指定ASCII编码:

val strArena = Arena.global().allocateFrom("2.2598258677677969", Charsets.US_ASCII)
val res = atof.invoke(strArena) as Double

内容的提问来源于stack exchange,提问作者elect

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 11:00:02