Skip to content

Instantly share code, notes, and snippets.

@XIII-th
Last active November 27, 2017 19:46
Show Gist options
  • Save XIII-th/4f0ed753a428ac874c8213d1f02200bd to your computer and use it in GitHub Desktop.
Save XIII-th/4f0ed753a428ac874c8213d1f02200bd to your computer and use it in GitHub Desktop.
JNI object meta loader
/*
Copyright 2017 Sergey Bubenshchikov (Sergey.V.Bubenshchikov@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
void test(JNIEnv * env, jobject j_matrix_object){
const char* class_name = "my/package/name/MatrixClass",
constructor_signature = "([[B)V",
method_name = "getData",
method_signature = "()[[B";
// load class meta
JObjectMeta* matrixContainer = JObjectMeta::loadInfo(
env,
class_name, constructor_signature,
method_name, method_signature
/*
method_name1, method_signature1,
method_name2, method_signature2,
etc...
*/
);
// call method
jobject dsId = env->CallIntMethod(j_matrix_object, dsPrototype->methods->at(method_name));
}
/*
Copyright 2017 Sergey Bubenshchikov (Sergey.V.Bubenshchikov@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "JObjectPrototype.h"
#include <stdarg.h>
JObjectMeta::JObjectMeta(jclass j_class, jmethodID j_methodId, map<const char*, jmethodID>* initMethods)
: cls(j_class), constructor(j_methodId), methods(initMethods)
{
}
JObjectMeta::~JObjectMeta()
{
if (methods)
delete methods;
}
JObjectMeta * JObjectMeta::loadInfo(JNIEnv * env, const char * clsName, const char * constructorSignature,
int methodsCount, ...)
{
// load class by name
jclass cls = env->FindClass(clsName);
if (env->ExceptionOccurred())
return NULL;
// take constructor by signature
jmethodID constructorId;
if(constructorSignature){
constructorId = env->GetMethodID(cls, "<init>", constructorSignature);
if (env->ExceptionOccurred())
return NULL;
} else
constructorId = NULL;
map<const char*, jmethodID>* initMethods = NULL;
if (methodsCount) {
initMethods = new map<const char*, jmethodID>();
// method name and signature inside of array
methodsCount *= 2;
va_list ap;
va_start(ap, methodsCount);
for (int i = 0; i < methodsCount; i+=2)
{
const char *methodName = va_arg(ap, const char*),
*methodSignature = va_arg(ap, const char*);
jmethodID methodId = env->GetMethodID(cls, methodName, methodSignature);
// is method found
if (env->ExceptionOccurred()) {
initMethods->clear();
// take an exception class with custom message
env->ExceptionClear();
jclass exClass = env->FindClass("java/lang/NoSuchMethodError");
if (env->ExceptionOccurred())
// ACHTUNG! we haven't base classes
return NULL;
// create custom message
char* message = new char[22 + strlen(methodName) + 20 + strlen(methodSignature) + 10 + strlen(clsName) + 1];
strcpy_s(message, 22, "Unable to find method ");
strcat_s(message, strlen(methodName), methodName);
strcat_s(message, 20, " with JNI signature ");
strcat_s(message, strlen(methodSignature), methodSignature);
strcat_s(message, 10, " at class ");
strcat_s(message, strlen(clsName), clsName);
strcat_s(message, 1, "\0");
env->ThrowNew(exClass, message);
delete[] message;
delete initMethods;
return NULL;
}
(*initMethods)[methodName] = methodId;
}
}
return new JObjectMeta(cls, constructorId, initMethods);
}
/*
Copyright 2017 Sergey Bubenshchikov (Sergey.V.Bubenshchikov@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
#include <jni.h>
#include <map>
using namespace std;
class JObjectMeta
{
JObjectMeta(jclass, jmethodID, map<const char*, jmethodID>*);
public:
~JObjectMeta();
const jclass cls;
const jmethodID constructor;
const map<const char*, jmethodID>* const methods;
static JObjectMeta* loadInfo(JNIEnv * env, const char* clsName, const char* constructorSignature, int methodsCount = 0, ...);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment