1

I'm trying to call from C++ into java. I've understood the cux of this answer but I feel I'm not able to achieve the last mile. What classes and methods do I have to use to call Java from C++?

Also not enough points to post comments on there. I basically get that I create the object from java and pass it along in one of my calls into C++. I then get that I could potentially cache it or immedately call into the callback.

This is how my djinni file looks like

my_client_interface = interface +j {
    log_string(str: string): bool;
}

get_my_record = interface +c {
  static create(): get_my_record;
  method_returning_nothing(value: i32);
  add_to_string(value: string);
  method_returning_something(key: my_record): my_record;
  set_callback(cb: my_client_interface);
}

I have no issue creating and passing along the logger callback from java but what concrete class do I call the logger against.

void GetMyRecordImpl::set_callback(const std::shared_ptr<MyClientInterface> & cb)
{
    cb->???????
}

since MyClientInterface is still abstract it errors out obviously with

error: member access into incomplete type 'std::__ndk1::shared_ptr<helloworld::MyClientInterface>::element_type' (aka 'helloworld::MyClientInterface')

But if I implement a concrete class against it obviously it's going to call the concrete classes log method and not the one in java. I do see what I need in

bool NativeMyClientInterface::JavaProxy::log_string(const std::string & c_str) {
  auto jniEnv = ::djinni::jniGetThreadEnv();
  ::djinni::JniLocalScope jscope(jniEnv, 10);
  const auto& data = ::djinni::JniClass<::djinni_generated::NativeMyClientInterface>::get();
  auto jret = jniEnv->CallBooleanMethod(Handle::get().get(), data.method_logString,
                                      ::djinni::get(::djinni::String::fromCpp(jniEnv, c_str)));
  ::djinni::jniExceptionCheck(jniEnv);
  return ::djinni::Bool::toCpp(jniEnv, jret);
}

but how would I create the NativeMyClientInterface object needed from the shared_pointer pointing to my abstract class MyClientInterface ?

rstr1112
  • 308
  • 4
  • 13

2 Answers2

1

I wasn't including #include "my_client_interface.hpp" :| the error makes so much sense now.

rstr1112
  • 308
  • 4
  • 13
1

If you want to use Java object in your C++ code, you got to implement and instantiate that object in Java. Djinni may be perceived as Java Native Interface (JNI) code generator. What you need is Java application, which parts are implemented in C++.

Each interface declared in Djinni is generated for C++ and Java (or Objective-C), so there must be two classes with implementation. One is generated by Djinni and it is a proxy that allows cross-language communication. The other one must be implemented by a programmer.

Regarding your compilation error, I believe you are missing an include directive in the file where GetMyRecordImpl is defined, something like:

#include "generated/MyClientInterface.hpp"
mkk
  • 675
  • 6
  • 17