interop

Crispin 2020-05-26T03:37:16.000900Z

Hi there interop experts!

Crispin 2020-05-26T03:37:35.001400Z

I'm having problems avoiding interop when calling a hava constructor.

Crispin 2020-05-26T03:37:43.001600Z

here is my code presently:

Crispin 2020-05-26T03:37:54.001900Z

(IntPointer. ^"[Ljava.lang.Integer;" (into-array Integer [(int 3)]))

Crispin 2020-05-26T03:38:04.002200Z

and its trying to invoke this constructor:

Crispin 2020-05-26T03:38:42.002700Z

and running it gives:

Crispin 2020-05-26T03:38:49.002900Z

No matching ctor found for class org.bytedeco.javacpp.IntPointer

Crispin 2020-05-26T03:39:03.003300Z

and decompiling my generated class file results in:

Crispin 2020-05-26T03:39:39.004Z

final IntPointer intPointer = (IntPointer)Reflector.invokeConstructor(RT.classForName("org.bytedeco.javacpp.IntPointer"), new Object[] { ((IFn)core$_main.const__2.getRawRoot()).invoke(core$_main.const__3, (Object)Tuple.create((Object)RT.intCast(3L))) });

seancorfield 2020-05-26T03:39:42.004100Z

It's looking for a native int array, you're passing an array of Integer objects.

Crispin 2020-05-26T03:40:05.004800Z

oooh. int is not Integer?! really... :thinking_face:

seancorfield 2020-05-26T03:40:13.005100Z

You want (int-array [3])

seancorfield 2020-05-26T03:40:25.005500Z

int is Primitive. Integer is a boxed object.

Crispin 2020-05-26T03:40:36.005700Z

ok that works

Crispin 2020-05-26T03:40:47.006100Z

thanks heaps @seancorfield

Crispin 2020-05-26T03:40:53.006300Z

🎉

Crispin 2020-05-26T03:53:49.006700Z

ok almost there... another one I don't understand

Crispin 2020-05-26T03:53:59.007Z

my code:

Crispin 2020-05-26T03:54:09.007200Z

(.exec ^org.bytedeco.qt.Qt5Widgets.QApplication app)

Crispin 2020-05-26T03:54:21.007400Z

invoking:

Crispin 2020-05-26T03:54:53.007900Z

giving:

Crispin 2020-05-26T03:55:01.008100Z

No matching field found: exec for class org.bytedeco.qt.Qt5Widgets.QApplication

Crispin 2020-05-26T03:55:08.008300Z

decompiled:

Crispin 2020-05-26T03:55:46.008600Z

final Object o2 = app;
        app = null;
        Object result = Reflector.invokeNoArgInstanceMember(o2, "exec", false);

Crispin 2020-05-26T03:56:25.008900Z

top of traceback:

Crispin 2020-05-26T03:56:28.009200Z

:trace
  [[clojure.lang.Reflector getInstanceField "Reflector.java" 397]
   [clojure.lang.Reflector
    invokeNoArgInstanceMember
    "Reflector.java"
    440]
   [decloj.core$_main invokeStatic "core.clj" 26]
   [decloj.core$_main doInvoke "core.clj" 10]

seancorfield 2020-05-26T03:57:13.009500Z

Because it's static, not an instance method.

seancorfield 2020-05-26T03:57:59.009800Z

(org.bytedeco.qt.Qt5Widgets.QApplication/exec) should call it

Crispin 2020-05-26T03:58:11.010Z

and pass in the app?

seancorfield 2020-05-26T03:58:52.010800Z

No, it's a static method with no arguments according to the declaration (although I'm not sure what native does in Java).

Crispin 2020-05-26T03:59:06.011100Z

ok thats what threw me

seancorfield 2020-05-26T03:59:16.011400Z

app is not involved in the call.

Crispin 2020-05-26T03:59:17.011500Z

its calling underlying cpp

seancorfield 2020-05-26T03:59:33.012Z

Yeah, JNI stuff...?

Crispin 2020-05-26T03:59:34.012100Z

ok, makes sense. that would be Qt's mainloop

Crispin 2020-05-26T03:59:36.012300Z

yep

Crispin 2020-05-26T04:02:53.012600Z

Ok. all working now

Crispin 2020-05-26T04:02:58.012800Z

Thanks heaps @seancorfield

Crispin 2020-05-26T04:03:24.013600Z

Qt GUI app in clojure using cpp bindings

Crispin 2020-05-26T04:04:01.014Z

now I'm gonna try graal native-imaging it...

seancorfield 2020-05-26T04:10:00.014200Z

Nice!