Re: a %downcast macro for Java needs the name of the JVM wrapper type for a call to jenv->FindClass

William S Fulton <[email protected]> Thu, 12 Jun 2025 21:18:43 +0100
Newsgroups gmane.comp.programming.swig
Message-ID <CANGqftDuYX-rY8DsBHCCAEXW-H43fQfaHxY5AYrrPTvPwW28kw@mail.gmail.com>
--===============3232327746329251211==
Content-Type: multipart/alternative; boundary="000000000000f6c646063765a446"

--000000000000f6c646063765a446
Content-Type: text/plain; charset="UTF-8"

Look at the $typemap special variable macro, but use it in a typemap. Good
examples in the Lib/java/std_vector.i file and also some tests in
Examples/testsuite/*.i. Documented in
https://swig.org/Doc4.3/Typemaps.html#Typemaps_special_macro_typemap.

On Tue, 10 Jun 2025 at 20:36, Alessio M <[email protected]>
wrote:

> For a given C++ type being wrapped, is it possible to get the
> (fully qualified) name of the wrapped type in the target language?
>
> I have many factory methods that return std::shared_ptr<const BaseClass>
> I do wrap and export to java several types derived from BaseClass
> And I need the runtime wrapper JVM managed type to accurately match those
> derived types
> I wrote the below %downcast macro
> I have a version of this for python which works quite nicely. It uses
> $descriptor(DeriverType) to create the python native extension type
>
> But JNI code does not seem to have any descriptor infrastructure in the
> module.
>
> Is there a way to make this work in Java?
>
> Thank you for any help you can provide
>
>
>
> // Helper function for %downcast, to be called for each target type
>
> %define %_downcast_const(Type)
>     {
>       auto const out = %dynptrcast(const Type,ptr);
>       if (out)
>       {
>         auto const clazz = jenv->FindClass(  >>>>>
> I_NEED_THE_JAVA_CLASS_NAME_HERE<<<<  );
>         if (clazz)
>         {
>           auto const mid = jenv->GetMethodID(clazz, "<init>", "(JZ)V");
>           if (mid)
>             return reinterpret_cast<jlong>(jenv->NewObject(clazz, mid,
> reinterpret_cast<jlong>(new %ptr(const Type)(out)), false));
>         }
>       }
>     }
> %enddef
>
>
>
> // the actual %downcast macro
>
> %define %downcast(typemaptarget, Types...)
>
> %fragment(%fragment_name(downcast, typemaptarget), "header") {
> jlong downcast(%ptr(const typemaptarget) const& ptr, JNIEnv *jenv)
> {
>   if (!ptr)
>     return 0; // TODO: check this is correct
>   else
>   {
>     %formacro(%_downcast_const, Types)
>   }
>   return 0;
> }
> }
>
> %typemap(jni) %ptr(typemaptarget) "jobject"
> %typemap(jtype) %ptr(typemaptarget) #typemaptarget
> %typemap(jstype) %ptr(typemaptarget) #typemaptarget
> %typemap(javaout) %ptr(typemaptarget) {
>   return $jnicall;
> }
>
> %typemap(out, fragment=%fragment_name(downcast, typemaptarget))
> %ptr(typemaptarget) {
>   $result = downcast($1, jenv);
>   if (!$1 || !$result)
>     SWIG_exception(SWIG_TypeError,"Actual object type could not be
> %downcasted. Consider adding derived types to %downcast declaration.");
> }
> %typemap(out, fragment=%fragment_name(downcast, typemaptarget)) %ptr(const
> typemaptarget) {
>   $result = downcast($1, jenv);
>   if (!$1 || !$result)
>     SWIG_exception(SWIG_TypeError,"Actual object type could not be
> %downcasted. Consider adding derived types to %downcast declaration.");
> }
> %typemap(out, fragment=%fragment_name(downcast, typemaptarget))
> %ptr(typemaptarget) const& {
>   $result = downcast(*$1, jenv);
>   if (!$1 || !$result)
>     SWIG_exception(SWIG_TypeError,"Actual object type could not be
> %downcasted. Consider adding derived types to %downcast declaration.");
> }
> %typemap(out, fragment=%fragment_name(downcast, typemaptarget)) %ptr(const
> typemaptarget) const& {
>   $result = downcast(*$1, jenv);
>   if (!$1 || !$result)
>     SWIG_exception(SWIG_TypeError,"Actual object type could not be
> %downcasted. Consider adding derived types to %downcast declaration.");
> }
>
> %enddef
> _______________________________________________
> Swig-user mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/swig-user
>

--000000000000f6c646063765a446
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Look at the $typemap special variable macro, but use it in=
 a typemap. Good examples in the Lib/java/std_vector.i file and also some t=
ests in Examples/testsuite/*.i. Documented in=C2=A0<a href=3D"https://swig.=
org/Doc4.3/Typemaps.html#Typemaps_special_macro_typemap">https://swig.org/D=
oc4.3/Typemaps.html#Typemaps_special_macro_typemap</a>.</div><br><div class=
=3D"gmail_quote gmail_quote_container"><div dir=3D"ltr" class=3D"gmail_attr=
">On Tue, 10 Jun 2025 at 20:36, Alessio M &lt;<a href=3D"mailto:masariello%=
[email protected]">[email protected]</a>&gt; wrote:<br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>=
For a given C++ type being wrapped, is it possible to get the (fully=C2=A0q=
ualified) name of the wrapped type in the target language?</div><div><br></=
div><div>I have many factory methods that return std::shared_ptr&lt;const B=
aseClass&gt;</div><div>I do wrap and export to java several types derived f=
rom BaseClass</div><div>And I need the runtime wrapper JVM managed type to =
accurately match those derived types</div><div>I wrote the below %downcast =
macro</div><div>I have a version of this for python which works quite nicel=
y. It uses $descriptor(DeriverType) to create the python native extension t=
ype</div><div><br></div><div>But JNI code does not seem to have any descrip=
tor infrastructure in the module.</div><div><br></div><div>Is there a way t=
o make this work in Java?</div><div><br></div><div>Thank you for any help=
=C2=A0you can provide</div><div><br></div><div><br></div><div><br></div><di=
v>// Helper function for %downcast, to be called for each target type<br><b=
r>%define %_downcast_const(Type)<br>=C2=A0 =C2=A0 {<br>=C2=A0 =C2=A0 =C2=A0=
 auto const out =3D %dynptrcast(const Type,ptr);<br>=C2=A0 =C2=A0 =C2=A0 if=
 (out)<br>=C2=A0 =C2=A0 =C2=A0 {<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto const =
clazz =3D jenv-&gt;FindClass(=C2=A0 &gt;&gt;&gt;&gt;&gt; I_NEED_THE_JAVA_CL=
ASS_NAME_HERE&lt;&lt;&lt;&lt;=C2=A0 );<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (c=
lazz)<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 {<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 auto const mid =3D jenv-&gt;GetMethodID(clazz, &quot;&lt;init&gt;&quot;=
, &quot;(JZ)V&quot;);<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (mid)<br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return reinterpret_cast&lt;jlong&gt;=
(jenv-&gt;NewObject(clazz, mid, reinterpret_cast&lt;jlong&gt;(new %ptr(cons=
t Type)(out)), false));<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>=C2=A0 =C2=A0 =
=C2=A0 }<br>=C2=A0 =C2=A0 }<br>%enddef<br><br><br><br>// the actual %downca=
st macro<br><br>%define %downcast(typemaptarget, Types...)<br><br>%fragment=
(%fragment_name(downcast, typemaptarget), &quot;header&quot;) {<br>jlong do=
wncast(%ptr(const typemaptarget) const&amp; ptr, JNIEnv *jenv)<br>{<br>=C2=
=A0 if (!ptr)<br>=C2=A0 =C2=A0 return 0; // TODO: check this is correct<br>=
=C2=A0 else<br>=C2=A0 {<br>=C2=A0 =C2=A0 %formacro(%_downcast_const, Types)=
<br>=C2=A0 }<br>=C2=A0 return 0;<br>}<br>}<br><br>%typemap(jni) %ptr(typema=
ptarget) &quot;jobject&quot;<br>%typemap(jtype) %ptr(typemaptarget) #typema=
ptarget<br>%typemap(jstype) %ptr(typemaptarget) #typemaptarget<br>%typemap(=
javaout) %ptr(typemaptarget) {<br>=C2=A0 return $jnicall;<br>}<br><br>%type=
map(out, fragment=3D%fragment_name(downcast, typemaptarget)) %ptr(typemapta=
rget) {<br>=C2=A0 $result =3D downcast($1, jenv);<br>=C2=A0 if (!$1 || !$re=
sult)<br>=C2=A0 =C2=A0 SWIG_exception(SWIG_TypeError,&quot;Actual object ty=
pe could not be %downcasted. Consider adding derived types to %downcast dec=
laration.&quot;);<br>}<br>%typemap(out, fragment=3D%fragment_name(downcast,=
 typemaptarget)) %ptr(const typemaptarget) {<br>=C2=A0 $result =3D downcast=
($1, jenv);<br>=C2=A0 if (!$1 || !$result)<br>=C2=A0 =C2=A0 SWIG_exception(=
SWIG_TypeError,&quot;Actual object type could not be %downcasted. Consider =
adding derived types to %downcast declaration.&quot;);<br>}<br>%typemap(out=
, fragment=3D%fragment_name(downcast, typemaptarget)) %ptr(typemaptarget) c=
onst&amp; {<br>=C2=A0 $result =3D downcast(*$1, jenv);<br>=C2=A0 if (!$1 ||=
 !$result)<br>=C2=A0 =C2=A0 SWIG_exception(SWIG_TypeError,&quot;Actual obje=
ct type could not be %downcasted. Consider adding derived types to %downcas=
t declaration.&quot;);<br>}<br>%typemap(out, fragment=3D%fragment_name(down=
cast, typemaptarget)) %ptr(const typemaptarget) const&amp; {<br>=C2=A0 $res=
ult =3D downcast(*$1, jenv);<br>=C2=A0 if (!$1 || !$result)<br>=C2=A0 =C2=
=A0 SWIG_exception(SWIG_TypeError,&quot;Actual object type could not be %do=
wncasted. Consider adding derived types to %downcast declaration.&quot;);<b=
r>}<br><br>%enddef<br></div></div>
_______________________________________________<br>
Swig-user mailing list<br>
<a href=3D"mailto:[email protected]" target=3D"_blank">Swig-u=
[email protected]</a><br>
<a href=3D"https://lists.sourceforge.net/lists/listinfo/swig-user" rel=3D"n=
oreferrer" target=3D"_blank">https://lists.sourceforge.net/lists/listinfo/s=
wig-user</a><br>
</blockquote></div>

--000000000000f6c646063765a446--


--===============3232327746329251211==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline


--===============3232327746329251211==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Swig-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/swig-user

--===============3232327746329251211==--