gpt4 book ai didi

java - Java 中的负短路到 NDK 中的 uint16_t 未正确处理?

转载 作者:行者123 更新时间:2023-12-02 11:16:01 27 4
gpt4 key购买 nike

我对在 Android NDK 中看到的将负短路作为参数的行为感到困惑。我已将其简化为一个简单的示例。

我有以下 c 函数:

void shortTest(uint16_t input)
{
uint16_t tmp = -1;
LogInfo("shortTest input: 0x%X\n", input); // wrapper for logging
LogInfo("shortTest tmp: 0x%X\n", tmp);
}

对应的Java签名:

void shortTest(short input);

该函数的调用方式如下:

short s = -1;
MyLibrary.INSTANCE.shortTest(s);

输出:

INFO   : 21:10:01:158 - shortTest:6158: shortTest input: 0xFFFFFFFF
INFO : 21:10:01:158 - shortTest:6159: shortTest tmp: 0xFFFF

此行为可能会导致失败,例如比较(输入不等于 tmp)。作为解决方法,我只是将 c 函数更改为采用 uint32_t 并传入 int。然而,我担心这会在其他领域影响我,因为我经常使用 uint16。它似乎以某种方式强制存储类型从 2 个字节到 4 个字节。我错过了什么吗?这是一个错误吗?

最佳答案

Java short 已签名,因此您在 shortTest 将接收到的内容方面对编译器撒了谎。

让我们通过查看以下 C 代码及其相应的 ARM 汇编来考虑这样做的后果:

// Here I'm using int16_t, because that's basically what you've declared that
// you will pass to shortTest from your Java code.
void shortTest(int16_t input) {
printf("shortTest input: 0x%X\n", input);
}

int main() {
shortTest(-1);
}

shortTest:
stmfd sp!, {r4, lr}
mov r1, r0 @ Just pass on input as the second argument to printf
movw r0, #:lower16:.LC0 @ Load string address
movt r0, #:upper16:.LC0 @ ...
bl printf @ Call printf
ldmfd sp!, {r4, pc} @ Return


main:
stmfd sp!, {r4, lr}
mvn r0, #0 @ First argument = 0xFFFFFFFF
bl shortTest @ Call shortTest
mov r0, #0 @ Value to return from main
ldmfd sp!, {r4, pc} @ Return

我的 main 这里将是您的 Java 代码,因此它将 0xFFFFFFFF 传递给 shortTest,这很好,因为它知道 shortTest 想要一个签名的短片。然后您到达 shortTest ,它(在您的情况下)认为它收到了一个无符号的短整型,但它假设调用者传递了正确类型的值,因此它不会执行任何零扩展。 p>

然后你尝试打印这个值,如果你的日志函数像 printf/sprintf 一样工作,它会隐式地将你的 short 提升为int,即它将打印一个 32 位值(不包括前导零)。本例中的 32 位值为 0xFFFFFFFF

关于java - Java 中的负短路到 NDK 中的 uint16_t 未正确处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50284482/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com