Null Callbacks

Mark Hammons mark.hammons at inaf.cnrs-gif.fr
Sun Feb 17 00:07:39 UTC 2019


If it's going to be fixed early next week, I'll probably put my project 
on hold till then. I don't see much point in putting in a manual 
workaround that might not be necessary (and will need to be ripped out) 
in a week or less. I'm going to research some other projects in the 
meantime that may be useful when it comes to this. Thanks for your help 
Jorn and Maurizio,

Mark

On 2/16/19 10:46 PM, Maurizio Cimadamore wrote:
> 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