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

2 ビュー (過去 30 日間)
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;
}

採用された回答

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

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeSimulink Coder についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by