I have a C++ API that looks like this:
class device
{
public:
virtual ~device();
virtual void disconnect() = 0;
virtual int read(void *dest, int num_bytes) = 0;
virtual int write(void const *src, int num_bytes) = 0;
};
typedef std::function<void(int xvalue, std::array<std::uint8_t, 8> address)> details_callback;
class dev_manager
{
public:
void start(std::string name, details_callback details);
void stop();
std::unique_ptr<device> connect(std::array<std::uint8_t, 8> address);
};
I am trying to use jni.hpp to create bindings to Java/Kotlin.
So far, it worked well. I use jni::RegisterNativePeer to create bindings to a "DevManager" Kotlin class.
The parts that are unclear so far though are:
- What do I do about connect() ? It returns a unique_ptr to an abstract base class. In the Kotlin class definition, I'd have something like
fun connect(address: ByteArray): Device. I currently have no idea how to properly wrap the return value here. One old-school method would be to pass the pointer as a long to the Kotlin code, and have it call native functions that accept that long as an argument. But that's old-school C style, as said. Can jni.hpp do this in a more modern C++ manner?
- How could the function object that is passed to start() be translated to Java/Kotlin?
Oh, also, currently, I manually use jni::Arrayjni::jbyte to read the address (since the address in Java/Kotlin is present as a byte array). So, I have code like this:
address to_address(jni::JNIEnv &env, jni::Array<jni::jbyte> const &byte_array)
{
jni::jsize array_size = byte_array.Length(env);
if (array_size != address().size())
throw exception("Invalid address bytearray size");
address addr;
for (jni::jsize i = 0; i < array_size; ++i)
addr[i] = byte_array.Get(env, i);
return addr;
}
However, I get the impression that jni.hpp could handle this automatically, that is, it can implement its own std::array<-> JNI array wrapper. Or did I misunderstand something?
I have a C++ API that looks like this:
I am trying to use jni.hpp to create bindings to Java/Kotlin.
So far, it worked well. I use jni::RegisterNativePeer to create bindings to a "DevManager" Kotlin class.
The parts that are unclear so far though are:
fun connect(address: ByteArray): Device. I currently have no idea how to properly wrap the return value here. One old-school method would be to pass the pointer as a long to the Kotlin code, and have it call native functions that accept that long as an argument. But that's old-school C style, as said. Can jni.hpp do this in a more modern C++ manner?Oh, also, currently, I manually use jni::Arrayjni::jbyte to read the address (since the address in Java/Kotlin is present as a byte array). So, I have code like this:
However, I get the impression that jni.hpp could handle this automatically, that is, it can implement its own std::array<-> JNI array wrapper. Or did I misunderstand something?