Click here to Skip to main content
13,259,779 members (45,251 online)
Click here to Skip to main content
Add your own
alternative version


46 bookmarked
Posted 13 Jan 2008

How to Call Java Functions from C Using JNI

, 13 Jan 2008
Rate this:
Please Sign up or sign in to vote.
This article covers calling Java functions from C using JNI. It also covers passing/returning simple parameters, arrays, and structure arrays in Java functions.


This article describes the methodology to use Java code in C/C++. I have not only discussed simple parameter passing and returning, but complex data structures such as structures and structure arrays to Java functions as well.


A few days ago, my manager asked me to write code in C/C++ that will use Java classes in other projects. It took me a lot of time to grab some information on how to call simple functions as well as pass/return complex data types. I found many articles describing C/C++ function calls in Java using JNI, but very few discussing calling Java functions in C/C++ using JNI. At that time, I decided to write an article so that other people could get help from it.

Using the code

The CTest.cpp file contains the code that calls different functions from Java classes. Java classes that are used in this project are given here under:

  • contains the functions that will be called from CTest.cpp. The other three Java classes are simply used in place of structures in Java. As there is no structure concept in Java, we can use classes for that purpose. That is what the other three .java files contain. contains the following functions that will be called from C/C++ code:

public static void main(String args[])

public static void TestCall(String szArg)

public static int DisplayStruct(ControlDetail ctrlDetail)

public static void DisplayStructArray(WorkOrder ArrWO[])

public static Object ReturnObjFunc()

To call these functions from C/C++, first you need to load the JVM using the following function:

JNIEnv* create_vm(JavaVM ** jvm) {
    JNIEnv *env;
    JavaVMInitArgs vm_args;

    JavaVMOption options; 
    //Path to the java source code     
    options.optionString = "-Djava.class.path=D:\\Java Src\\TestStruct"; 
    vm_args.version = JNI_VERSION_1_6; //JDK version. This indicates version 1.6
    vm_args.nOptions = 1;
    vm_args.options = &options;
    vm_args.ignoreUnrecognized = 0;
    int ret = JNI_CreateJavaVM(jvm, (void**)&env, &vm_args);
    if(ret < 0)
        printf("\nUnable to Launch JVM\n");       
    return env;

Kindly note that to use this code, you will have to modify the options.optionString variable. You will have to set the path of the Java code: where the Java classes are placed. Currently, it being set to D:\Java Src\TestStruct. You can modify it to you situation. You will also need to modify the JDK version information in the above code, as shown below:

vm_args.version = JNI_VERSION_1_6; //JDK version. This indicates version 1.6

Modify it if you have another JDK version installed.

To call a specific Java function from C, you need to do the following:

  1. Obtain the class reference using the FindClass(,,) method.
  2. Obtain the method IDs of the functions of the class that you want to call using the GetStaticMethodID and GetMethodID function calls.
  3. Call the functions using CallStaticVoidMethod, CallStaticIntMethod, and CallStaticObjectMethod.

One important thing to be noted here is specifying the function signatures while obtaining the method IDs.

To obtain the correct method signature, you can use the following Java command:

javap -s -p HelloWorld

It will display you the signature of each function in the HelloWorld class. These signatures can be used to obtain the method IDs. The result of the above command can be seen below:

D:\Java Src\TestStruct>javap -s -p HelloWorld
Compiled from ""
public class HelloWorld extends java.lang.Object{
public HelloWorld();
  Signature: ()V
public static void main(java.lang.String[]);
  Signature: ([Ljava/lang/String;)V
public static void TestCall(java.lang.String);
  Signature: (Ljava/lang/String;)V
public static int DisplayStruct(ControlNEDetail);
  Signature: (LControlNEDetail;)I
public static void DisplayStructArray(WorkOrder[]);
  Signature: ([LWorkOrder;)V
public static java.lang.Object ReturnObjFunc();
  Signature: ()Ljava/lang/Object;

Kindly note that while specifying the method name in the GetMethodID function, if the method is a constructor, then its method name will be <init>.


Before traveling down a difficult path, it is important to understand the basic concepts and to have various frameworks and tools installed on your computer.

  1. You will need the Sun Java Developer Kit (JDK). I recommend Java 1.6.0.
  2. Any C/C++ compiler installed.

How to run

To use this code, follow the instructions below:

  • Compile the *.java files using the javac command.
  • Compile the CTest.cpp file using any C++ compiler; I used MSVC++ 6.

Converting this code to pure C from C++

The attached code is written in C++. To convert this code into pure C, you will have to modify the following in the CTest.cpp file:



instead of:



This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Software Developer (Senior)
United Kingdom United Kingdom
Ahmad Qarshi is an IT Consultant and have good expertise in different development technologies. He loves to code in .NET, JavaFX, Delphi, XSLT/Schematron. Above all very keen to learn new stuff Smile | :)

You may also be interested in...


Comments and Discussions

QuestionJNI load error - main class not found Pin
alien_invader1-Mar-10 12:17
memberalien_invader1-Mar-10 12:17 
AnswerRe: JNI load error - main class not found Pin
alien_invader26-Apr-10 10:27
memberalien_invader26-Apr-10 10:27 
GeneralMy application crashes while calling JNI_CreateJavaVM function Pin
Khalid Noor22-Feb-10 0:06
memberKhalid Noor22-Feb-10 0:06 
GeneralRe: My application crashes while calling JNI_CreateJavaVM function Pin
ajalilqarshi22-Feb-10 3:28
memberajalilqarshi22-Feb-10 3:28 
GeneralRe: My application crashes while calling JNI_CreateJavaVM function Pin
Khalid Noor23-Feb-10 2:15
memberKhalid Noor23-Feb-10 2:15 
GeneralRe: My application crashes while calling JNI_CreateJavaVM function Pin
ajalilqarshi23-Feb-10 3:13
memberajalilqarshi23-Feb-10 3:13 
GeneralRe: My application crashes while calling JNI_CreateJavaVM function [modified] Pin
Khalid Noor23-Feb-10 20:27
memberKhalid Noor23-Feb-10 20:27 
GeneralRe: My application crashes while calling JNI_CreateJavaVM function Pin
Member 41280638-Mar-11 1:20
memberMember 41280638-Mar-11 1:20 
GeneralRe: My application crashes while calling JNI_CreateJavaVM function Pin
pratikmota9-May-11 23:55
memberpratikmota9-May-11 23:55 
GeneralSOLVED: Error message: "Can't find dependent libraries" [modified] Pin
tsjakkaa29-Jan-10 3:25
membertsjakkaa29-Jan-10 3:25 
Generalhelp me to sort out the error [modified] Pin
shariqmohd26-Jan-10 18:06
membershariqmohd26-Jan-10 18:06 
GeneralRe: help me to sort out the error Pin
ajalilqarshi27-Jan-10 14:09
memberajalilqarshi27-Jan-10 14:09 
QuestionNot working for me ...... pls help!!! Pin
kumarmukt20-Jan-10 4:20
memberkumarmukt20-Jan-10 4:20 
GeneralRE: How to Call Java functions from C Using JNI Pin
chinmaya.mishra961-Aug-09 7:46
memberchinmaya.mishra961-Aug-09 7:46 

I compiled the CTest.cpp. But I got error that "unable to open StdAfx.h and jni.h ". Can any body help me?

I am attaching the Source code:


#include "StdAfx.h"
#include &lt;stdio.h&gt;
#include &lt;jni.h&gt;
#include &lt;string.h&gt;

#define PATH_SEPARATOR ';' /* define it to be ':' on Solaris */
#define USER_CLASSPATH "." /* where Prog.class is */

struct ControlDetail
     int ID;
     char Name[100];
     char IP[100];
     int Port;

struct WorkOrder
     char          sumSerialId[20];    
     char          accessNumber[18];
     char          actionType[4];
     char          effectiveDate[24];
     char          fetchFlag[2];
     char          reason[456];
     char          accessSource[100];    

JNIEnv* create_vm(JavaVM ** jvm) {
      JNIEnv *env;
      JavaVMInitArgs vm_args;
      JavaVMOption options;
      options.optionString = "-Djava.class.path=D:\\Java Src\\TestStruct"; //Path to the java source code
      vm_args.version = JNI_VERSION_1_5; //JDK version. This indicates version 1.5
      vm_args.nOptions = 1;
      vm_args.options = &amp;options;
      vm_args.ignoreUnrecognized = 0;
      int ret = JNI_CreateJavaVM(jvm, (void**)&amp;env, &amp;vm_args);
      if(ret &lt; 0)
           printf("\nUnable to Launch JVM\n");       
     return env;

int main(int argc, char* argv[])
     JNIEnv *env;
     JavaVM * jvm;
     env = create_vm(&amp;jvm);
     if (env == NULL)
          return 1;
     struct ControlDetail ctrlDetail;    
     ctrlDetail.ID = 11;
     ctrlDetail.Port = 9099;
     printf("Struct Created in C has values:\nID:%d\nName:%s\n IP:%s\nPort:%d\n",ctrlDetail.ID,ctrlDetail.Name,ctrlDetail.IP,ctrlDetail.Port);

     struct WorkOrder WO[2];
     strcpy(WO[0].effectiveDate,"25-12-2007 12:20:30 PM");
     strcpy(WO[0].fetchFlag, "0");
     strcpy(WO[0].reason,"Executed Successfully");
     strcpy(WO[1].effectiveDate,"25-12-2007 11:20:30 PM");

      jclass clsH=NULL;
      jclass clsC = NULL;
      jclass clsW = NULL;
     jclass clsR = NULL;
      jmethodID midMain = NULL;
      jmethodID midCalling = NULL;
      jmethodID midDispStruct = NULL;
      jmethodID midDispStructArr = NULL;
     jmethodID midRetObjFunc = NULL;
      jmethodID midCtrlDetConst = NULL;
      jmethodID midWoConst = NULL;
      jobject jobjDet = NULL;
     jobject jobjRetData = NULL;
      jobjectArray jobjWOArr = NULL;
      //Obtaining Classes
      clsH = env-&gt;FindClass("HelloWorld");
      clsC = env-&gt;FindClass("ControlDetail");
      clsW = env-&gt;FindClass("WorkOrder");
     //Obtaining Method IDs
      if (clsH != NULL)
          midMain         = env-&gt;GetStaticMethodID(clsH, "main", "([Ljava/lang/String;)V");
          midCalling      = env-&gt;GetStaticMethodID(clsH,"TestCall","(Ljava/lang/String;)V");
          midDispStruct = env-&gt;GetStaticMethodID(clsH,"DisplayStruct","(LControlDetail;)I");
          midDispStructArr = env-&gt;GetStaticMethodID(clsH,"DisplayStructArray","([LWorkOrder;)V");
          midRetObjFunc = env-&gt;GetStaticMethodID(clsH,"ReturnObjFunc","()Ljava/lang/Object;");
           printf("\nUnable to find the requested class\n");          
     if(clsC != NULL)
          //Get constructor ID for ControlDetail
          midCtrlDetConst = env-&gt;GetMethodID(clsC, "&lt;init&gt;", "(ILjava/lang/String;Ljava/lang/String;I)V");         
           printf("\nUnable to find the requested class\n");          

     if(clsW != NULL)
          //Get Constructor ID for WorkOrder
          midWoConst = env-&gt;GetMethodID(clsW, "&lt;init&gt;", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");         
           printf("\nUnable to find the requested class\n");          

     /* Now we will call the functions using the their method IDs               */
     if(midMain != NULL)
          env-&gt;CallStaticVoidMethod(clsH, midMain, NULL); //Calling the main method.
     if (midCalling!=NULL)
          jstring StringArg = env-&gt;NewStringUTF("\nTestCall:Called from the C Program\n");
          //Calling another static method and passing string type parameter
     printf("\nGoing to Call DisplayStruct\n");
     if (midDispStruct!=NULL)
          if(clsC != NULL &amp;&amp; midCtrlDetConst != NULL)
               jstring StringArgName = env-&gt;NewStringUTF(ctrlDetail.Name);
               jstring StringArgIP = env-&gt;NewStringUTF(ctrlDetail.IP);
               //Creating the Object of ControlDetail.
               jobjDet = env-&gt;NewObject(clsC, midCtrlDetConst, (jint)ctrlDetail.ID, StringArgName, StringArgIP, (jint)ctrlDetail.Port);
          if(jobjDet != NULL &amp;&amp; midDispStruct != NULL)
               env-&gt;CallStaticIntMethod(clsH,midDispStruct,jobjDet); //Calling the method and passing ControlDetail Object as parameter
     //Calling a function from java and passing Structure array to it.
     printf("\n\nGoing to call DisplayStructArray From C\n\n");
     if (midDispStructArr!=NULL)
          if(clsW != NULL &amp;&amp; midWoConst != NULL)
               //Creating the Object Array that will contain 2 structures.
               jobjWOArr = (jobjectArray)env-&gt;NewObjectArray(2,clsW,env-&gt;NewObject(clsW, midWoConst,env-&gt;NewStringUTF(""),env-&gt;NewStringUTF(""),env-&gt;NewStringUTF(""),
               //Initializing the Array
               for(int i=0;i&lt;2;i++)
                    env-&gt;SetObjectArrayElement(jobjWOArr,i,env-&gt;NewObject(clsW, midWoConst,env-&gt;NewStringUTF(WO[i].sumSerialId),
          //Calling the Static method and passing the Structure array to it.
          if(jobjWOArr != NULL &amp;&amp; midDispStructArr != NULL)
     //Calling a Static function that return an Object
     if (midRetObjFunc != NULL)
          //Calling the function and storing the return object into jobject type variable
          //Returned object is basically a structure having two fields (string and integer)
          jobjRetData = (jobject)env-&gt;CallStaticObjectMethod(clsH,midRetObjFunc,NULL);
          //Get the class of object
          clsR = env-&gt;GetObjectClass(jobjRetData);
          //Obtaining the Fields data from the returned object
          jint nRet = env-&gt;GetIntField(jobjRetData,env-&gt;GetFieldID(clsR,"returnValue","I"));
          jstring jstrLog = (jstring)env-&gt;GetObjectField(jobjRetData,env-&gt;GetFieldID(clsR,"Log","Ljava/lang/String;"));
          const char *pLog = env-&gt;GetStringUTFChars(jstrLog,0);
          printf("\n\nValues Returned from Object are:\nreturnValue=%d\nLog=%s",nRet,pLog);
          //After using the String type data release it.
     //Release resources.
     int n = jvm-&gt;DestroyJavaVM();
      return 0;

Java Codes

public class ControlNEDetail
     public int ID;
     public String Name;
     public String IP;
     public int Port;

     public ControlNEDetail(int nID, String szName, String szIP, int nPort)
          this.ID = nID;
          this.Name = szName;
          this.IP = szIP;
          this.Port = nPort;

public class ReturnData
     int returnValue;
     String Log;
     public ReturnData(int nRetVal, String szLog)
          this.returnValue = nRetVal;
          this.Log = szLog;

public class WorkOrder
     String          sumSerialId;    
     String          accessNumber;
     String          actionType;
     String          effectiveDate;
     String          fetchFlag;
     String          reason;
     String          accessSource;
     public WorkOrder(String szSumID,String szAccNum, String szActType, String szEffectDate, String fetchFlg, String szReason, String szAccSrc )
          this.sumSerialId = szSumID;
          this.accessNumber = szAccNum;
          this.actionType = szActType;
          this.effectiveDate = szEffectDate;
          this.fetchFlag = fetchFlg;
          this.reason = szReason;
          this.accessSource = szAccSrc;              

public class HelloWorld
         public static void main(String args[])
            System.out.println("Hello World!");
            System.out.println("This is the main function in HelloWorld class");
         public static void TestCall(String szArg)
         public static int DisplayStruct(ControlNEDetail ctrlDetail)
              System.out.println("Structure is:\n-------------------------");
              System.out.println("Name:" + ctrlDetail.Name);
              System.out.println("IP:" + ctrlDetail.IP);
              System.out.println("Port" + ctrlDetail.Port);
              return 1;
         public static void DisplayStructArray(WorkOrder ArrWO[])
              System.out.println("WorkOrders are Given hereunder:\n----------------------------");
              for(int i = 0; i&lt; ArrWO.length;i++)
                   System.out.println("&lt;---Work Order Number:" + String.valueOf(i+1) + "&lt;---");
                   System.out.println("Sum_Serial_ID: " + ArrWO[i].sumSerialId);
                   System.out.println("Access_Number: " + ArrWO[i].accessNumber);
                   System.out.println("Action_Type: " + ArrWO[i].actionType);
                   System.out.println("Effective_Date: " + ArrWO[i].effectiveDate);
                   System.out.println("Fetch_Flag: " + ArrWO[i].fetchFlag);
                   System.out.println("Reason: " + ArrWO[i].reason);
                   System.out.println("Access_Source: " + ArrWO[i].accessSource);

         public static Object ReturnObjFunc()
              System.out.println("Going to return an object from java");
              ReturnData RetData = new ReturnData(1,"Successfull function call");
              return RetData;


GeneralRe: RE: How to Call Java functions from C Using JNI Pin
Mohammed Anees14-Aug-09 0:20
memberMohammed Anees14-Aug-09 0:20 
GeneralVS 2008 Pin
thusithagh5-Jul-09 9:47
memberthusithagh5-Jul-09 9:47 
GeneralMy vote of 2 Pin
thusithagh5-Jul-09 7:54
memberthusithagh5-Jul-09 7:54 
Questionjvm.dll not found Pin
gdaley9-Jun-09 18:34
membergdaley9-Jun-09 18:34 
AnswerRe: jvm.dll not found Pin
gdaley9-Jun-09 19:50
membergdaley9-Jun-09 19:50 
GeneralJNI_CreateJavaVM returning -3 Pin
rostronix14-May-09 16:34
memberrostronix14-May-09 16:34 
GeneralUnknown Error Pin
Ankush M Gupta18-Oct-08 5:47
memberAnkush M Gupta18-Oct-08 5:47 
QuestionRe: Unknown Error Pin
jakko00724-Feb-09 1:36
memberjakko00724-Feb-09 1:36 
AnswerRe: Unknown Error Pin
Damos25-Mar-09 8:44
memberDamos25-Mar-09 8:44 
GeneralRe: Unknown Error Pin
Jagdish Vasani12-Jun-09 5:16
memberJagdish Vasani12-Jun-09 5:16 
Generalundeclared identifier.. Pin
bujal1-Jul-08 21:50
memberbujal1-Jul-08 21:50 
GeneralRe: undeclared identifier.. Pin
ajalilqarshi30-Jul-08 1:22
memberajalilqarshi30-Jul-08 1:22 
Questionhow can i do webservice Pin
norazanita30-Jun-08 18:45
membernorazanita30-Jun-08 18:45 
QuestionHow can i create jvm in dll? Pin
Member 108979217-Jun-08 0:08
memberMember 108979217-Jun-08 0:08 
AnswerRe: How can i create jvm in dll? Pin
ajalilqarshi30-Jul-08 1:32
memberajalilqarshi30-Jul-08 1:32 
AnswerRe: How can i create jvm in dll? Pin
jakko00724-Feb-09 1:46
memberjakko00724-Feb-09 1:46 
GeneralRe: How can i create jvm in dll? Pin
RAJKUMARV23-Jun-10 2:27
memberRAJKUMARV23-Jun-10 2:27 
QuestionHow about Pin
Jim Crafton14-Jan-08 4:35
memberJim Crafton14-Jan-08 4:35 
AnswerRe: How about Pin
ajalilqarshi14-Jan-08 6:48
memberajalilqarshi14-Jan-08 6:48 
GeneralRe: How about Pin
Jim Crafton14-Jan-08 7:37
memberJim Crafton14-Jan-08 7:37 
GeneralRe: How about Pin
ajalilqarshi14-Jan-08 20:15
memberajalilqarshi14-Jan-08 20:15 
GeneralRe: How about Pin
Jim Crafton15-Jan-08 4:08
memberJim Crafton15-Jan-08 4:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.171114.1 | Last Updated 13 Jan 2008
Article Copyright 2008 by ajalilqarshi
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid