Skip to content
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

fixed direct-mapping type-mapped pointer result types #319

Merged
merged 3 commits into from
May 13, 2014
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions native/dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,9 @@ fromNativeTypeMapped(JNIEnv* env, jobject from_native, void* resp, ffi_type* typ
if (type->type != FFI_TYPE_POINTER) {
extract_value(env, obj, result, type->size, JNI_TRUE);
}
else {
*(jobject*)result = obj;
}
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions native/testlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,14 @@ returnInt32Argument(int32_t arg) {
return arg;
}

EXPORT int*
returnPoint(int x, int y) {
int *p = malloc(2 * sizeof(int));
p[0] = x;
p[1] = y;
return p;
}

EXPORT int64_t
returnInt64Zero() {
int64_t value = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/com/sun/jna/DefaultTypeMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public void addFromNativeConverter(Class cls, FromNativeConverter converter) {
/** Add a {@link TypeConverter} to provide bidirectional mapping between
* a native and Java type.
*/
protected void addTypeConverter(Class cls, TypeConverter converter) {
public void addTypeConverter(Class cls, TypeConverter converter) {
addFromNativeConverter(cls, converter);
addToNativeConverter(cls, converter);
}
Expand Down
44 changes: 44 additions & 0 deletions test/com/sun/jna/DirectTypeMapperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@

package com.sun.jna;

import java.awt.Point;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import junit.framework.TestCase;
Expand Down Expand Up @@ -156,6 +158,48 @@ public void testIntegerToBooleanResultConversion() throws Exception {
assertFalse("Failed to convert integer return to boolean FALSE",
lib.returnInt32Argument(false));
}
public static class DirectTypeMappedResultTypeTestLibrary {
public native Point returnPoint(int x, int y);
static {
Map options = new HashMap();
DefaultTypeMapper mapper = new DefaultTypeMapper();
mapper.addTypeConverter(Point.class, new TypeConverter() {
public Object fromNative(Object value, FromNativeContext context) {
Pointer p = (Pointer) value;
int x = p.getInt(0), y = p.getInt(4);
Native.free(Pointer.nativeValue(p));
return new Point(x, y);
}
public Object toNative(Object value, ToNativeContext context) {
return Pointer.NULL; // dummy implementation (not called)
}
public Class nativeType() {
return Pointer.class;
}
});
options.put(Library.OPTION_TYPE_MAPPER, mapper);

// Can't extend java.awt.Point; can't add:
// public final static TypeMapper TYPE_MAPPER = mapper;
// -> Extend Native.options via reflection:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Were these other issues you ran into? Could you please elaborate?

try {
Field f = Native.class.getDeclaredField("options");
f.setAccessible(true);
((Map) f.get(null)).put(Point.class, options);
}
catch (Exception e) {
throw new RuntimeException(e);
}

Native.register(NativeLibrary.getInstance("testlib", options));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Native.register isn't properly forwarding type mapper options, perhaps that should be part of this patch?

}
}
public void testTypeMapperResultTypeConversion() throws Exception {
DirectTypeMappedResultTypeTestLibrary lib = new DirectTypeMappedResultTypeTestLibrary();
Point p = lib.returnPoint(1234, 5678);
assertEquals("Failed to convert int* return to java.awt.Point", 1234, p.x);
assertEquals("Failed to convert int* return to java.awt.Point", 5678, p.y);
}

public static void main(String[] args) {
junit.textui.TestRunner.run(DirectTypeMapperTest.class);
Expand Down