How to call Java functions from C++?
As an example, check Creating a JVM from C. It shows a sample procedure to create a JVM and invoke a method. If the JVM already exists; e.g. your C program is invoked by the Java program (callback situation), you can cache the JNIEnv* pointer.
As an advice, be careful caching pointers to the JVM from C/C++, there are some semantics involved as to what you can cache and it could be invoked later on. For that, as Brian Agnew pointed out, check the JNI reference.
Calling Java functions from C language
I solved this by making my class into my own package.
When we did not define any package it is taking as default package.
So I created my own package something like this
package com.aqu.vvn
I know its a work around but doing this worked for me.
I will let u know the exact way when I figured out.
Calling Java methods from C without starting the JVM from C
As JJF stated, this is definitely possible! I'll show an example below, assuming you already know how to call Java methods from C, but without having to create a JVM!
First, we have a Java class test.Test.java
that calls the native method methodA
:
package test;
public class Test {
static {
System.loadLibrary("test");
}
private native void methodA();
public static void methodB() {
System.out.println("Java: Method B has executed!");
}
public static void main(String[] args) {
new Test().methodA();
}
}
Next, we have the header file created by javah
or javac -h
:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class test_Test */
#ifndef _Included_test_Test
#define _Included_test_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: test_Test
* Method: methodA
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_test_Test_methodA
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
Below is the C file which holds the native method methodA
:
#include <jni.h>
#include <stdio.h>
#include "test_Test.h"
void callMethodB(JNIEnv *env);
JNIEXPORT void JNICALL Java_test_Test_methodA(JNIEnv *env, jobject thisObj) {
printf("C: Method A executed!\n"); fflush(stdout);
callMethodB(env);
return;
}
void callMethodB(JNIEnv *env) {
jclass testClass = (*env) -> FindClass(env, "test/Test");
jmethodID methodB = (*env) -> GetStaticMethodID(env, testClass, "methodB", "()V");
(*env) -> CallStaticVoidMethod(env, testClass, methodB, NULL);
return;
}
The output of this program is:
C: Method A executed!
Java: Method B has executed!
Remember to create a test.dll
file with your preferred GNU compiler.
Call Java function from C++ method
As an example, check Creating a JVM from C. It shows a sample procedure to create a JVM and invoke a method. If the JVM already exists; e.g. your C program is invoked by the Java program (callback situation), you can cache the JNIEnv* pointer.
As an advice, be careful caching pointers to the JVM from C/C++, there are some semantics involved as to what you can cache and it could be invoked later on.
Source: How to call Java functions from C++?
How to call Java function from c
You can't reuse JNIEnv
because it is specific to the calling thread. To call (non-static) Java method from the native code, you need something like this:
static JavaVM *gJavaVM;
static jobject gCallbackObject = NULL;
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
gJavaVM = vm;
return JNI_VERSION_1_6;
}
JNIEXPORT void JNICALL JNI_FUNCTION(AndroidActivity_nativeInit)(JNIEnv* env, jobject obj, int width, int height) {
// ...
gCallbackObject = (*env)->NewGlobalRef(env, obj);
}
JNIEXPORT void JNICALL JNI_FUNCTION(AndroidActivity_nativeRelease)(JNIEnv* env, jobject obj) {
(*env)->DeleteGlobalRef(env, gCallbackObject);
gCallbackObject = NULL;
}
//this method is called from native code
void nativeSayHello(char* msg) {
int status;
JNIEnv *env;
int isAttached = 0;
if (!gCallbackObject) return;
if ((status = (*gJavaVM)->GetEnv(gJavaVM, (void**)&env, JNI_VERSION_1_6)) < 0) {
if ((status = (*gJavaVM)->AttachCurrentThread(gJavaVM, &env, NULL)) < 0) {
return;
}
isAttached = 1;
}
jclass cls = (*env)->GetObjectClass(env, gCallbackObject);
if (!cls) {
if (isAttached) (*gJavaVM)->DetachCurrentThread(gJavaVM);
return;
}
jmethodID method = (*env)->GetMethodID(env, cls, "SayHello", "(Ljava/lang/String;)V");
if (!method) {
if (isAttached) (*gJavaVM)->DetachCurrentThread(gJavaVM);
return;
}
jstring string = (*mEnv)->NewStringUTF(mEnv, msg);
(*env)->CallVoidMethod(env, gCallbackObject, method, string);
if (isAttached) (*gJavaVM)->DetachCurrentThread(gJavaVM);
}
This code snippet is not tested. To prevent memory leak, don't forget to call nativeRelease()
method in your Java code when the reference to the object will not needed any more.
See The Java Native Interface documentation for more details.
Related Topics
How to Get Stock Quotes Using Google Finance API
What Is the Most Appropriate Way to Store User Settings in Android Application
Populating a Listview Using an Arraylist
Rjava Load Error in Rstudio/R After "Upgrading" to Osx Yosemite
How to Convert a Byte Array to a Hex String in Java
What Causes and What Are the Differences Between Noclassdeffounderror and Classnotfoundexception
Explanation of Classcastexception in Java
Why Is It Considered a Bad Practice to Omit Curly Braces
What Is a Stringindexoutofboundsexception - How to Fix It
Can't Create Directory in Android 10
Execution Failed For Task :App:Compiledebugjavawithjavac in Android Studio
When to Use Linkedlist Over Arraylist in Java