<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Yes, I do want ObjC methods invoking Java code. And yes I'd use JNI handles if I were using JNI.<div class=""><br class=""></div><div class="">I looked into MethodHandles, of course, but the problem is that the ObjC runtime expects a pointer to a function that takes at least 2 arguments: the `self` on which the ObjC method was called, and the method selector (see <a href="https://developer.apple.com/documentation/objectivec/1418901-class_addmethod?language=objc" class="">https://developer.apple.com/documentation/objectivec/1418901-class_addmethod?language=objc</a> ). So I can do it, but either I'd have to receive the calls in a static Java method with no way to link the ObjC `self` with the Java `this`, or I could use an instance method having to create a new ObjC class for each object because the MethodHandle would map to a different native function pointer for each different `this`.</div><div class=""><br class=""></div><div class="">I considered the approach you suggest with a map of ints/longs to all currently allocated Java objects that represent ObjC objects, but I kinda dismissed it because it felt like that map would be a bottleneck. But since you say the decision to not allow native Java object handles was intentional, I'll try it.</div>
<div><br class=""><blockquote type="cite" class=""><div class="">2 дек. 2022 г., в 16:11, Sundararajan Athijegannathan <<a href="mailto:sundararajan.athijegannathan@oracle.com" class="">sundararajan.athijegannathan@oracle.com</a>> написал(а):</div><br class="Apple-interchange-newline"><div class=""><meta charset="UTF-8" class=""><div class="elementToProof" style="font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; background-color: rgb(255, 255, 255);">Suppose if you have to implement the same with JNI, would you use JNI handles? i.e., Pass a JNI handle as a void* to native callbacks and map it back to Java objects inside the callbacks?</div><div class="elementToProof" style="font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; background-color: rgb(255, 255, 255);"><br class=""></div><div class="elementToProof" style="font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; background-color: rgb(255, 255, 255);">Panama does not support something like JNI handles. <span class="ContentPasted0" style="color: rgb(29, 28, 29); font-family: Slack-Lato, Slack-Fractions, appleLogo, sans-serif; font-size: 15px; font-variant-ligatures: common-ligatures; orphans: 2; text-align: left; widows: 2; background-color: rgb(248, 248, 248); display: inline !important;">It's something we considered/discussed and so far the risk outweighed the benefits.</span></div><div class="elementToProof" style="font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; background-color: rgb(255, 255, 255);"><span class="ContentPasted0" style="color: rgb(29, 28, 29); font-family: Slack-Lato, Slack-Fractions, appleLogo, sans-serif; font-size: 15px; font-variant-ligatures: common-ligatures; orphans: 2; text-align: left; widows: 2; background-color: rgb(248, 248, 248); display: inline !important;"><br class=""></span></div><div class="elementToProof" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; orphans: 2; widows: 2;"><font color="#1d1c1d" face="Slack-Lato, Slack-Fractions, appleLogo, sans-serif" class=""><span style="caret-color: rgb(29, 28, 29); font-size: 15px; background-color: rgb(248, 248, 248);" class="">One solution could be to pass "longs" to native API and have a Map of long to Java object on the Java side (to map 'native object' to Java mirror back).</span></font></div><div class="elementToProof" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; orphans: 2; widows: 2;"><font color="#1d1c1d" face="Slack-Lato, Slack-Fractions, appleLogo, sans-serif" class=""><span style="caret-color: rgb(29, 28, 29); font-size: 15px; background-color: rgb(248, 248, 248);" class=""><br class=""></span></font></div><div class="elementToProof" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; orphans: 2; widows: 2;"><font color="#1d1c1d" face="Slack-Lato, Slack-Fractions, appleLogo, sans-serif" class=""><span style="caret-color: rgb(29, 28, 29); font-size: 15px; background-color: rgb(248, 248, 248);" class="">Thanks,</span></font></div><div class="elementToProof" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; orphans: 2; widows: 2;"><font color="#1d1c1d" face="Slack-Lato, Slack-Fractions, appleLogo, sans-serif" class=""><span style="caret-color: rgb(29, 28, 29); font-size: 15px; background-color: rgb(248, 248, 248);" class="">-Sundar</span></font></div><div id="appendonsend" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""></div><hr tabindex="-1" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; display: inline-block; width: 842.796875px;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class=""></span><div id="divRplyFwdMsg" dir="ltr" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><font face="Calibri, sans-serif" style="font-size: 11pt;" class=""><b class="">From:</b><span class="Apple-converted-space"> </span>panama-dev <<a href="mailto:panama-dev-retn@openjdk.org" class="">panama-dev-retn@openjdk.org</a>> on behalf of Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com" class="">maurizio.cimadamore@oracle.com</a>><br class=""><b class="">Sent:</b><span class="Apple-converted-space"> </span>02 December 2022 18:03<br class=""><b class="">To:</b><span class="Apple-converted-space"> </span>Gregory Klyushnikov <<a href="mailto:grishka93@gmail.com" class="">grishka93@gmail.com</a>>; <a href="mailto:panama-dev@openjdk.org" class="">panama-dev@openjdk.org</a> <<a href="mailto:panama-dev@openjdk.org" class="">panama-dev@openjdk.org</a>><br class=""><b class="">Subject:</b><span class="Apple-converted-space"> </span>Re: Conversion between Java objects and native pointers</font><div class=""> </div></div><div class="BodyFragment" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;"><font size="2" class=""><span style="font-size: 11pt;" class=""><div class="PlainText">To make sure I understand your use case (admittedly I'm not an expert in<span class="Apple-converted-space"> </span><br class="">ObjC). You want to define an ObjC class whose methods end up invoking<span class="Apple-converted-space"> </span><br class="">some piece of Java code? Would that be a fair description?<br class=""><br class="">In general, "Java objects" cannot be converted into native pointers.<span class="Apple-converted-space"> </span><br class="">But, you can turn Java methods (method handles, to be precise) into<span class="Apple-converted-space"> </span><br class="">native pointers, and pass those to the ObjC class implementation. Would<span class="Apple-converted-space"> </span><br class="">that be enough?<br class=""><br class="">Maurizio<br class=""><br class="">On 02/12/2022 11:20, Gregory Klyushnikov wrote:<br class="">> I'm trying to use the preview Panama API to build an FFI for Objective C, allowing Java to fully interoperate with native macOS libraries. Calling out to existing classes is simple: you just use objc_msgSend and sel_registerName a bunch with the right arguments. But many macOS APIs want you to create your own classes and override methods (NSApplicationDelegate is one example and you seemingly can't do GUI without creating one) — which isn't as easy to do in a non-ugly way with the current Panama API.<br class="">><br class="">> You *can* define a new Objective C class at runtime using objc_registerClassPair, but you don't have a good way of linking an ObjC object to its corresponding Java object. You can, obviously, store the pointer to the ObjC object in the Java object, but you can't do it the other way around, which poses a problem for overridden methods. The obvious solution to receiving calls to overridden methods would be:<br class="">> 1. Set their implementations as pointers to static methods<br class="">> 2. Create an instance variable in the ObjC object that would hold the pointer to its corresponding Java object<br class="">> 3. When a method is called, you'd get your Java `this` from that instance variable and forward the call to your Java object<br class="">><br class="">> But I can't seem to find any way whatsoever, at least one that doesn't feel extremely hacky and thus unreliable, to convert a Java object to a native pointer and back. This would also be useful, in some circumstances, for those C APIs that take a function pointer and `void*` as the "context" and then pass that `void*` back to your function. Or are there better solutions that don't need this?</div></span></font></div></div></blockquote></div><br class=""></body></html>