Can a C++ s-function that uses JNI to interface with a Java class be built into an executable with Simulink Coder?

2 visualizaciones (últimos 30 días)
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;
}

Respuesta aceptada

Randal Guendel
Randal Guendel el 17 de Jun. de 2015
I answered my own question: yes, Simulink Coder is able to handle the interface with Java. My problem was the call to DestroyJavaVM.

Más respuestas (0)

Categorías

Más información sobre Simulink Coder en Help Center y File Exchange.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by