Can a C++ s-function that uses JNI to interface with a Java class be built into an executable with Simulink Coder?
2 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Randal Guendel
am 16 Jun. 2015
Beantwortet: Randal Guendel
am 17 Jun. 2015
I'm trying to make use of some 3rd party Java classes within a Simulink model. I've created a C++ wrapper to the classes that uses JNI, and I've built an s-function of that wrapper. It works fine when I run the model within Simulink, and I'm able to use the Coder to build an executable. However, running the executable fails with the following message:
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x000000000040e4d2, pid=20518, tid=140630443198240
#
# JRE version: OpenJDK Runtime Environment (7.0_79-b14) (build 1.7.0_79-mockbuild_2015_05_14_07_23-b00)
# Java VM: OpenJDK 64-Bit Server VM (24.79-b02 mixed mode linux-amd64 compressed oops)
# Derivative: IcedTea 2.5.5
# Distribution: CentOS release 6.6 (Final), package rhel-2.5.5.3.el6_6-x86_64 u79-b14
# Problematic frame:
# C [test_java_as_RSIM+0xe4d2]
#
I wondered if anything about the Coder would preclude the Java interface, and if not, whether anyone has any suggestions on getting this to work.
My code is as follows:
#include <stdio.h>
#include <jni.h>
#include "java_convert.h"
JNIEnv* get_or_create_vm(JavaVM **jvm, int* gc)
{
JNIEnv* env;
JavaVMInitArgs args;
JavaVMOption* options = new JavaVMOption[1];
args.version = JNI_VERSION_1_6;
args.nOptions = 1;
options[0].optionString = (char *)"-Djava.class.path=./myjavalibs/thirdparty.jar";
args.options = options;
args.ignoreUnrecognized = false;
int n;
int status;
// try to get and attach to existing VM first
status = JNI_GetCreatedJavaVMs(jvm, 1, (jsize*) &n);
if (status == JNI_OK && n == 1) {
status = (*jvm)->AttachCurrentThread((void**)&env, &args);
}
// if not successful, create a new VM
if (status != JNI_OK || n != 1) {
status = JNI_CreateJavaVM(jvm, (void**)&env, &args);
*gc = 1;
}
//status = JNI_CreateJavaVM(jvm, (void**)&env, &args);
delete options;
return env;
}
jdouble invoke_class(JNIEnv* env, jdouble cas, jdouble altitude)
{
jclass thirdparty_class;
jmethodID convert_method;
thirdparty_class = env->FindClass("common/utils/aClass");
jthrowable exc;
exc = env->ExceptionOccurred();
if (exc) {
env->ExceptionDescribe();
env->ExceptionClear();
}
else {
convert_method = env->GetStaticMethodID(thirdparty_class, "convertCasToTas", "(DD)D");
return env->CallStaticDoubleMethod(thirdparty_class, convert_method, cas, altitude);
}
}
double call_java_class(double cas, double altitude)
{
JavaVM *jvm = NULL;
JNIEnv *env = NULL;
int gc = 0;
env = get_or_create_vm(&jvm, &gc);
if(env == NULL)
return -1;
double tas = invoke_class(env, cas, altitude);
if (gc == 1) {
jvm->DestroyJavaVM();
}
return tas;
}
0 Kommentare
Akzeptierte Antwort
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu Simulink Coder finden Sie in Help Center und File Exchange
Produkte
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!