Skip to content

Problem passing Union ByValue w/ leading int #1118

@jeog

Description

@jeog

Apologies if this is something obvious but I've looked through the docs, google forum, and stack overflow and couldn't find anything.

I'm having an issue passing a union by value whose first field is an int. I've simplified the issue to the following:

(Note - the library is implemented in C++ and is accessed through a stable ABI layer in C; details below the code sections)

C/C++

typedef union{
    int a;
    double b;
    int c;
} test_union;

EXTERN_C_SPEC_ DLL_SPEC_ int
UnionTest_ABI( int a, int b, test_union test, int c, int d);

int
UnionTest_ABI( int a, int b, test_union test, int c, int d)
{
    switch(b){
    case 0:
        std::cout<< "UNIONTEST: 0 : a=" << a << " b=" << b << " VAL="
                 << test.a << " c=" << c << " d=" << d << std::endl;
        break;
    case 1:
        std::cout<< "UNIONTEST: 1 : a=" << a << " b=" << b << " VAL="
                 << test.b << " c=" << c << " d=" << d << std::endl;
        break;
    case 2:
        std::cout<< "UNIONTEST: 2 : a=" << a << " b=" << b << " VAL="
        << test.c << " c=" << c << " d=" << d << std::endl;
    }
    return 0;
}

Java

public interface CLib extends Library {
   public static class TestUnion extends Union {
        public int a;
        public double b;
        public int c;
      
        public static class ByValue extends TestUnion implements Union.ByValue {            
        };
    }

  int UnionTest_ABI( int a, int b, TestUnion.ByValue v, int c, int d);
}

Test

        CLib.TestUnion.ByValue testUnion = new CLib.TestUnion.ByValue();
        testUnion.c = 33; 
        testUnion.setType(Integer.TYPE);

        getCLib().UnionTest_ABI( 1, 2, testUnion, 7,8);

C Output

UNIONTEST: 2 : a=1 b=2 VAL=7 c=8 d=-737409248

The int/union is not being passed in and args 'c' and 'd' are one position to the 'left'. Some type of alignment issue I guess? As you can imagine this does or does not crash in different ways depending on the function.

But, if I change the Java Union to the following, it works:

    public static class TestUnion extends Union {
        public long a;
        public double b;
        public int c;
      
        public static class ByValue extends TestUnion implements Union.ByValue {            
        };
    }

JRE

# JRE version: OpenJDK Runtime Environment (8.0_212-b03) (build 1.8.0_212-8u212-b03-2~deb9u1-b03)
# Java VM: OpenJDK 64-Bit Server VM (25.212-b03 mixed mode linux-amd64 compressed oops)

JNA

Java Native Access (JNA) API Version 5
Version: 5.3.1 (b0)
 Native: 6.0.0 (147a998f0cbc89681a1ae6c0dd121629)
 Prefix: linux-x86-64

System

Linux debian 4.19.0-0.bpo.4-amd64 #1 SMP Debian 4.19.28-2~bpo9+1 (2019-03-27) x86_64 GNU/Linux

Lib

file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
g++ -std=c++0x -DTHIS_EXPORTS_INTERFACE -O0 -g3 -Wall -c --DDEBUG -fPIC 

Thanks,
jon

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions