Null Callbacks

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Sat Feb 16 21:46:08 UTC 2019


Sorry to hear about this.

The problems you mention should be fixed early next week - as Jorn said, 
there are places where you can get builds from - but I also don't see 
why we couldn't refresh the binary snapshot. It seems like these issues 
are common enough that will probably be encountered by other developers 
too, and it is very hard to workaround them.

Speaking of workarounds, as Jorn mentioned - the key is having a 
function in some header which mentions that problematic struct. Maybe 
there is some other header with a function that takes that struct as an 
argument, or that returns it? Or, maybe, an hacky workaround would be to 
create one such header by hand and bind it?

Maurizio

On 16/02/2019 15:48, Mark Hammons wrote:
> I'll keep that in mind Jorn, thanks. I found an alternative workaround 
> (I found the default function that was being used in place of the 
> callback if the callback was null, and just turned that into my 
> callback), but now it seems I'm truly blocked by the issue I posted 
> about yesterday: Exception in thread "main" 
> java.lang.UnsupportedOperationException: bitsSize on Unresolved.
>
> Using jextract on wlroots introduced a lot of new headers, and a lot 
> of cross-header dependencies. There's a struct defined as:
>
> ```
>
> @NativeStruct("[${wl_signal}(destroy)${wl_signal}(new_input)${wl_signal}(new_output)](anon$backend_h$444)") 
>
>     public interface anon$backend_h$444 extends 
> Struct<backend.anon$backend_h$444> {
>         @NativeLocation(
>             file = "/usr/include/wlr/backend.h",
>             line = 23,
>             column = 20
>         )
>         @NativeGetter("destroy")
>         wl_signal destroy$get();
>
>         @NativeSetter("destroy")
>         void destroy$set(wl_signal var1);
>
>         @NativeAddressof("destroy")
>         Pointer<wl_signal> destroy$ptr();
>
>         @NativeLocation(
>             file = "/usr/include/wlr/backend.h",
>             line = 25,
>             column = 20
>         )
>         @NativeGetter("new_input")
>         wl_signal new_input$get();
>
>         @NativeSetter("new_input")
>         void new_input$set(wl_signal var1);
>
>         @NativeAddressof("new_input")
>         Pointer<wl_signal> new_input$ptr();
>
>         @NativeLocation(
>             file = "/usr/include/wlr/backend.h",
>             line = 27,
>             column = 20
>         )
>         @NativeGetter("new_output")
>         wl_signal new_output$get();
>
>         @NativeSetter("new_output")
>         void new_output$set(wl_signal var1);
>
>         @NativeAddressof("new_output")
>         Pointer<wl_signal> new_output$ptr();
>     }
>
> ```
>
> and it cannot be instantiated. The ```val l2 = 
> Libraries.bind(MethodHandles.lookup(), classOf[wlroots.backend])``` 
> trick that worked yesterday doesn't work for this either so I'm kinda 
> roadblocked.
>
> Mark
>
> On 2/16/19 4:31 PM, Jorn Vernee wrote:
>> Hi Mark,
>>
>> An API for getting a null callback is currently in the process of 
>> being added [1].
>>
>> In the meantime, there is a way to work around this, but it's tricky 
>> since there doesn't seem to be a public API for parsing a Function 
>> descriptor, or a public API to easily get a layout for a 
>> NativeCallback class (will make a note of that as well). AFAICT it 
>> currently requires manually constructing the Function descriptor for 
>> the callback. But, you should be able to use something like this:
>>
>> ```
>>     @NativeCallback("()v")
>>     public interface FI1 {
>>         void run();
>>     }
>>
>>     public static <T> T pointerLiteral(LayoutType<T> type, long value) {
>>         try(Scope scope = Scope.newNativeScope()) {
>>             Pointer<Long> ptr = scope.allocate(NativeTypes.UINT64);
>>             ptr.set(value);
>>             return ptr.cast(NativeTypes.VOID).cast(type).get();
>>         }
>>     }
>>
>>     public static void main(String[] args) {
>>         Function f = Function.ofVoid(false, NativeTypes.VOID.layout());
>>         Address a = Address.ofFunction(64, f);
>>         Callback<FI1> nullCB = 
>> pointerLiteral(LayoutType.ofFunction(a, FI1.class), 0);
>>         System.out.println(nullCB.entryPoint().isNull()); // prints 
>> 'true'
>>     }
>> ```
>>
>> Hope that helps,
>> Jorn
>>
>> [1] : 
>> https://mail.openjdk.java.net/pipermail/panama-dev/2019-February/004373.html
>>
>> Mark Hammons schreef op 2019-02-16 15:53:
>>> Hi,
>>>
>>> I'm back with a new wayland problem. More specifically, my problem is
>>> with a helper library called wlroots. One of its functions,
>>> wlr_backend_autocreate takes a function pointer as an argument. The
>>> big problem here is that jextract represents this as a Callback<Fi1>,
>>> and part of the valid input for this parameter is the null pointer. So
>>> the question is, how do I create a null callback? Can it even be done
>>> with foreign as it's currently made?
>>>
>>> Thanks,
>>>
>>> Mark Hammons


More information about the panama-dev mailing list