JNA将Java布尔值映射到-1整数吗? [英] JNA maps Java boolean to -1 integer?

查看:195
本文介绍了JNA将Java布尔值映射到-1整数吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在JNA结构中传递boolean值时,我正在使用的本机库收到令人惊讶的警告:

I am getting a suprising warning from the native library I am using when passing a boolean value in a JNA structure:

value of pCreateInfo->clipped (-1) is neither VK_TRUE nor VK_FALSE

在此库中,VK_TRUEVK_FALSE分别#定义为1和0.

In this library VK_TRUE and VK_FALSE are #defined as 1 and 0 respectively.

结构本身并不特别复杂,其他所有东西似乎都可以正常工作(本机库似乎将'undefined'布尔值视为false),但无论如何这里都是这样的:

The structure itself isn't particularly complex and everything else appears to be working (the native library seems to treat the 'undefined' boolean as false), but here it is anyway:

public class VkSwapchainCreateInfoKHR extends Structure {
    public int sType;
    public Pointer pNext;
    public int flags;
    public Pointer surface;
    public int minImageCount;
    public int imageFormat;
    public int imageColorSpace;
    public VkExtent2D imageExtent;
    public int imageArrayLayers;
    public int imageUsage;
    public int imageSharingMode;
    public int queueFamilyIndexCount;
    public Pointer pQueueFamilyIndices;
    public int preTransform;
    public int compositeAlpha;
    public int presentMode;
    public boolean clipped;       // <--------- this is the field in question
    public Pointer oldSwapchain;
}

如果clipped字段为false,则没有警告,如果为true,则得到警告-似乎JNA正在将true映射为整数-1?

If the clipped field is false there is no warning, if it's true then I get the warning - it appears JNA is mapping true to integer -1?

此库使用的本机布尔值并不多,但是只要将其设置为true(其他所有方法都可以正常工作),我都会得到相同的行为.

There are not many native boolean values used by this library but I get the same behaviour whenever one is set to true (and again everything else works fine).

特别是,如果我将clipped更改为int并将值显式设置为1或0,则一切正常!

In particular, if I change clipped to be an int and set the value explicitly to 1 or 0 everything works!

JNA布尔值true的默认值为-1吗?

Is -1 the default value for JNA boolean true?

如果是这样,我将如何覆盖类型映射?

If so, how would I go about over-riding the type mapping?

还是我应该只手动使用int?

Or should I just use int 'manually'?

推荐答案

JNA通过libffi映射到本机库. libffi中没有bool类型,因此必须使用其他映射-JNA的

JNA maps to native libraries via libffi. There is no bool type in libffi so other mappings must be used -- JNA's default type mapping chooses to map boolean to ffi_type_uint32. This works in the structure(s) because it happens to match the 32-bit mapping size, but not the definition: in C, 0 is false and anything nonzero is true. Only if the native type is also boolean does this 0/non-zero interpretation regain meaning as false/true.

使用FFIJNIboolean关键字进行的网络搜索可以发现多个示例,例如这一个这一个通过FFI或JNI访问库并且不符合布尔值的0/1要求时,将发生不可预测的结果.后面的示例与这种情况非常相似,在这种情况下,将真正的Java boolean解释为值为<1的C int.

A web search using FFI or JNI and boolean keywords can uncover multiple examples such as this one and this one where unpredictable results occur when libraries are accessed via FFI or JNI and do not conform to the 0 / 1 requirement for boolean values. The latter example appears very similar to this case where a true Java boolean is interpreted as a C int with a value other than 1.

在FFI和您的库之间的某个地方,可能在已编译的字节码和/或依赖于平台/编译器的类型转换中,可能会对0x00000000应用按位的非"运算,从而将其转换为0xffffffff在C语言中仍然是"true".

Somewhere under the hood between FFI and your library, and possibly in compiled byte code and/or platform/compiler-dependent type conversions, it's likely that a bitwise "not" is being applied to 0x00000000, turning it into 0xffffffff which is still 'true' in C.

最重要的是,默认情况下,JNA会将Java布尔false映射为32位本机值0,而将Java布尔true映射为非0的32位本机值.可以假设.如果您的库要求true的整数值为1,请使用您可以专门设置的整数类型,或者使用boolean的自定义类型映射为您将int设置为0或1. JNA的 W32APITypeMapper BOOL类型,a>将此转换为1或0的示例.

The bottom line is that JNA will by default map Java boolean false to a 32-bit native value of 0, and a Java boolean true to a 32-bit native value that is not 0, and that's all that can be assumed. If your library requires true to have an integer value of 1, either use an integer type that you can specifically set, or use a custom Type Mapping for boolean that sets an int to 0 or 1 for you. JNA's W32APITypeMapper has an example of this conversion to 1 or 0 for the Windows BOOL type.

在您的情况下,假设您正在映射VkSwapchainCreateInfoKHR结构在此处定义clipped的类型为VkBool32:

In your case, assuming you are mapping the VkSwapchainCreateInfoKHR structure defined here, the type of clipped is VkBool32:

typedef struct VkSwapchainCreateInfoKHR {
    VkStructureType                  sType;
    const void*                      pNext;
    VkSwapchainCreateFlagsKHR        flags;
    VkSurfaceKHR                     surface;
    uint32_t                         minImageCount;
    VkFormat                         imageFormat;
    VkColorSpaceKHR                  imageColorSpace;
    VkExtent2D                       imageExtent;
    uint32_t                         imageArrayLayers;
    VkImageUsageFlags                imageUsage;
    VkSharingMode                    imageSharingMode;
    uint32_t                         queueFamilyIndexCount;
    const uint32_t*                  pQueueFamilyIndices;
    VkSurfaceTransformFlagBitsKHR    preTransform;
    VkCompositeAlphaFlagBitsKHR      compositeAlpha;
    VkPresentModeKHR                 presentMode;
    VkBool32                         clipped;
    VkSwapchainKHR                   oldSwapchain;
} VkSwapchainCreateInfoKHR;

哪里...

typedef uint32_t VkBool32;

因此int是正确的映射-您需要将clipped映射到32位整数正如您在答案中指出的那样,添加您自己的类型映射器,以更好地处理这些int值!

So int is the correct mapping here -- you need to map clipped to a 32-bit integer As you've pointed out in your answer, it is simple to add your own type mapper to better handle these int values!

(在检查类型映射时,对于pQueueFamilyIndices字段,您可能会发现IntByReferencePointer更好的映射.)(您的映射对于可变长度是正确的int数组.)

(While I'm reviewing the type mappings, you might find IntByReference a better mapping than Pointer for the pQueueFamilyIndices field.) (Your mapping is correct for a variable length int array.)

这篇关于JNA将Java布尔值映射到-1整数吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆