-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
wrong mapping of union inside structure #223
Comments
Seeing the native declaration and JNA mapping would help, and a test case would be superb. On Apr 22, 2013, at 10:53 AM, folkfreund wrote:
|
The original code is far too complex for posting here. I'll try to create a test case. public static interface IReqDoneListener extends Callback
{
void callback(REQ_PEND req);
} I will post my test case or any other results soon. |
I couldn't find a possibility to upload files... JNA_union_test.java package jna_union_test;
import com.sun.jna.Callback;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.Union;
import java.util.Arrays;
import java.util.List;
/**
* Test to reproduce issue #223: "wrong mapping of union inside structure"
*/
public class JNA_union_test
{
public static class TheUnion extends Union
{
public int u_integer;
public float u_float;
public double u_double;
}
public static class TheStruct extends Structure
{
public long s_long;
public TheUnion s_union;
public int s_valueAfterUnion;
@Override
protected List getFieldOrder()
{
return Arrays.asList(new String[] {
"s_long",
"s_union",
"s_valueAfterUnion"
});
}
@Override
public String toString()
{
String sizeInfo = "TheUnion Size="+s_union.size()+"\n----------------\n";
return sizeInfo + super.toString();
}
}
public interface TestDll extends Library
{
public static interface ITestCallback extends Callback
{
void callback(TheStruct result);
}
void invokeCallback(ITestCallback callback);
}
public static class DllListener implements TestDll.ITestCallback
{
@Override
public void callback(TheStruct result)
{
System.out.println();
System.out.println("Structure built by DLL");
System.out.println("-----------------------");
System.out.println(result.toString());
}
}
public static void main(String[] args)
{
Native.setProtected(true);
final TestDll testDll = (TestDll)Native.loadLibrary("JNA_test_dll", TestDll.class);
if (testDll == null)
{
System.out.println("cannot load JNA_test_dll");
return;
}
// first print the structure built on the Java side
System.out.println("Structure built by Java");
System.out.println("-----------------------");
TheStruct theStruct = new TheStruct();
theStruct.s_long = 0x12345l;
theStruct.s_union = new TheUnion();
theStruct.s_union.setType("u_integer");
theStruct.s_union.u_integer = 0x4321;
theStruct.s_union.write();
theStruct.s_valueAfterUnion = 0x5555;
theStruct.write();
System.out.println(theStruct.toString());
// nest print the structure as built on the native side,
// (the DLL will create a struct with the same values as above)
testDll.invokeCallback(new DllListener());
}
} And the code of the JNA_test_dll.dll typedef union
{
int u_integer;
float u_float;
double u_double;
} TheUnion;
typedef struct
{
long s_long;
TheUnion s_union;
int s_valueAfterUnion;
} TheStruct;
TheStruct myResult;
void invokeCallback (void (*callback) (TheStruct *result) )
{
if (callback)
{
myResult.s_long = 0x12345l;
myResult.s_union.u_integer = 0x4321;
myResult.s_valueAfterUnion = 0x5555;
(* callback)(&myResult);
}
} The output says (commented):
|
Usually what you do with github is fork the repo and apply changes to that repo, then post a pull request against the original. "gist" also exists for uploading code snippets independent of a particular repo. On Apr 23, 2013, at 5:54 AM, folkfreund wrote:
|
Thanks for the info - I'm new to github, but I will have to learn using it ;-) Greetings, folkfreund |
When the callback receives the union, it has no way of knowing the correct type and thus can't perform an automatic read to synch Java fields with native memory. You need to either set a "safe" default type in your union ctor, or do the Try calling |
The post-union field is definitely using an incorrect offset. The total structure size should be 20 bytes, not 32, and the field offset should be 16, not 24. |
…java-native-access#223) Motivation: With 91c90cb in we don't need a direct dependency on epoll anymore Modifications: Remove dependency Result: Cleanup
Just migrated a project from JNA 3.2.7 to 3.5.2
One of the structures contains a union and other fields after that union.
With the new version the fields after the union are mapped to wrong addresses - as if all fields of the union were present. The memory dump by toString shows "deafbeef".
In other words:
The Union's function size() reports the correct value (8), but the next field of the structure is placed 0x20 bytes after the start of the union (0x20 is the sum of all fields inside the union)
The text was updated successfully, but these errors were encountered: