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

Map null callback objects to null pointers #77

Merged
merged 1 commit into from
Sep 21, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
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
5 changes: 4 additions & 1 deletion libtest/ClosureTest.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

int testClosureNull(int (*closure)(void), int defaultValue)
{
return closure ? (*closure)() : defaultValue;
}
void testClosureVrV(void (*closure)(void))
{
(*closure)();
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/jnr/ffi/provider/jffi/NativeClosureManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ private ClosureSite(NativeClosureFactory<T> factory) {
}

public Pointer toNative(T value, ToNativeContext context) {
if (value == null) {
return null;
}

// If passing down a function pointer, don't re-wrap it
if (value instanceof ClosureFromNativeConverter.AbstractClosurePointer) {
return (ClosureFromNativeConverter.AbstractClosurePointer) value;
Expand Down
24 changes: 24 additions & 0 deletions src/test/java/jnr/ffi/DelegateTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ public void tearDown() {
}

public static interface TestLib {
public static interface CallableNull {
@Delegate public int call();
}
int testClosureNull(CallableNull closure, int defaultValue);
public static interface CallableVrV {
@Delegate public void call();
}
Expand Down Expand Up @@ -151,6 +155,26 @@ public interface ReusableCallable {
public CallableIrV ret_pointer(CallableIrV callable);
}
@Test
public void closureNullWithValue() {
final boolean[] called = { false };
final TestLib.CallableNull closure = new TestLib.CallableNull() {

public int call() {
called[0] = true;
return 42;
}
};
int retValue = lib.testClosureNull(closure, 41);
assertTrue("Callable not called", called[0]);
assertEquals("Incorrect return value from callable", 42, retValue);
}
@Test
public void closureNullWithNull() {
final TestLib.CallableNull closure = null;
int retValue = lib.testClosureNull(closure, 41);
assertEquals("Incorrect return value from callable", 41, retValue);
}
@Test
public void closureVrV() {
final boolean[] called = { false };
final TestLib.CallableVrV closure = new TestLib.CallableVrV() {
Expand Down