How to call Java code from C/C++

I wanted to call Java functions from C++ and searching in the internet I found some codes but seems lacking more details. What I will do here is to make it complete.

CALLING JAVA IN C++ USING MS VISUAL STUDIO 2008

Requirements:
-JDK ( I used jdk1.7.0_55 32bit) 
-Visual Studio 2008

Procedure:
1. Add the library "jvm.lib". Remember this library exist when you install the JDK


2. Add the 2 path of the include files of the JDK























3. Add the library path























4. Create the Java source and compile them (javac * to compile everything in the folder). The source location in my MS Windows environment is D:\MyFiles\Downloads\Java Src\TestStruct

//HelloWorld.java
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)
      {
      System.out.println(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< ArrWO.length;i++)
      {
      System.out.println("<---work i="" number:="" order="" p="" string.valueof="">      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;
      }
}

//ControlNEDetail.java
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;
}
}

//ReturnData.java
public class ReturnData
{
int returnValue;
String Log;

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

//WorkOrder.java
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;
}
};

5. Create the C++ code,

#include "StdAfx.h"
#include <stdio.h>
#include <jni.h>
#include <string.h>

 #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:\\MyFiles\\Downloads\\Java Src\\TestStruct;D:\\MyFiles\\RetailPlatform\\rpscom\\ExternalLibs\\JavaPOS\\1.13.2\\dist\\jpos1132.jar"; //Path to the java source code
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;
}

int main(int argc, char* argv[])
{
JNIEnv *env;
JavaVM * jvm;
env = create_vm(&jvm);
if (env == NULL)
return 1;

struct ControlDetail ctrlDetail;
ctrlDetail.ID = 11;
strcpy(ctrlDetail.Name,"HR-HW");
strcpy(ctrlDetail.IP,"10.32.164.133");
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].sumSerialId,"2000");
strcpy(WO[0].accessNumber,"2878430");
strcpy(WO[0].actionType,"04");
strcpy(WO[0].effectiveDate,"25-12-2007 12:20:30 PM");
strcpy(WO[0].fetchFlag, "0");
strcpy(WO[0].reason,"Executed Successfully");
strcpy(WO[0].accessSource,"PMS");
strcpy(WO[1].sumSerialId,"1000");
strcpy(WO[1].accessNumber,"2878000");
strcpy(WO[1].actionType,"T4");
strcpy(WO[1].effectiveDate,"25-12-2007 11:20:30 PM");
strcpy(WO[1].fetchFlag,"0");
strcpy(WO[1].reason,"");
strcpy(WO[1].accessSource,"RMS");


    jclass clsH=NULL;
jclass clsJ=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->FindClass("HelloWorld");
clsJ = env->FindClass("jpos/BaseControl");
    clsC = env->FindClass("ControlDetail");
    clsW = env->FindClass("WorkOrder");

//Obtaining Method IDs
    if (clsH != NULL)
    {
midMain       = env->GetStaticMethodID(clsH, "main", "([Ljava/lang/String;)V");
midCalling    = env->GetStaticMethodID(clsH,"TestCall","(Ljava/lang/String;)V");
midDispStruct = env->GetStaticMethodID(clsH,"DisplayStruct","(LControlDetail;)I");
midDispStructArr = env->GetStaticMethodID(clsH,"DisplayStructArray","([LWorkOrder;)V");
midRetObjFunc = env->GetStaticMethodID(clsH,"ReturnObjFunc","()Ljava/lang/Object;");
}
else
    {
    printf("\nUnable to find the requested class\n");    
    }
if(clsC != NULL)
{
//Get constructor ID for ControlDetail
midCtrlDetConst = env->GetMethodID(clsC, "", "(ILjava/lang/String;Ljava/lang/String;I)V");
}
else
    {
    printf("\nUnable to find the requested class\n");    
    }

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

/************************************************************************/
/* Now we will call the functions using the their method IDs */
/************************************************************************/
if(midMain != NULL)
env->CallStaticVoidMethod(clsH, midMain, NULL); //Calling the main method.

if (midCalling!=NULL)
{
jstring StringArg = env->NewStringUTF("\nTestCall:Called from the C Program\n");
//Calling another static method and passing string type parameter
env->CallStaticVoidMethod(clsH,midCalling,StringArg);
}

printf("\nGoing to Call DisplayStruct\n");
if (midDispStruct!=NULL)
{
if(clsC != NULL && midCtrlDetConst != NULL)
{
jstring StringArgName = env->NewStringUTF(ctrlDetail.Name);
jstring StringArgIP = env->NewStringUTF(ctrlDetail.IP);

//Creating the Object of ControlDetail.
jobjDet = env->NewObject(clsC, midCtrlDetConst, (jint)ctrlDetail.ID, StringArgName, StringArgIP, (jint)ctrlDetail.Port);
}

if(jobjDet != NULL && midDispStruct != NULL)
env->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 && midWoConst != NULL)
{
//Creating the Object Array that will contain 2 structures.
jobjWOArr = (jobjectArray)env->NewObjectArray(2,clsW,env->NewObject(clsW, midWoConst,env->NewStringUTF(""),env->NewStringUTF(""),env->NewStringUTF(""),
 env->NewStringUTF(""),env->NewStringUTF(""),env->NewStringUTF(""),env->NewStringUTF("")));        
//Initializing the Array
for(int i=0;i<2 i="" p=""> {
env->SetObjectArrayElement(jobjWOArr,i,env->NewObject(clsW, midWoConst,env->NewStringUTF(WO[i].sumSerialId),
env->NewStringUTF(WO[i].accessNumber),
env->NewStringUTF(WO[i].actionType),
env->NewStringUTF(WO[i].effectiveDate),
env->NewStringUTF(WO[i].fetchFlag),
env->NewStringUTF(WO[i].reason),
env->NewStringUTF(WO[i].accessSource)));
}
}
//Calling the Static method and passing the Structure array to it.
if(jobjWOArr != NULL && midDispStructArr != NULL)
env->CallStaticVoidMethod(clsW,midDispStructArr,jobjWOArr);
}
//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->CallStaticObjectMethod(clsH,midRetObjFunc,NULL);
//Get the class of object
clsR = env->GetObjectClass(jobjRetData);
//Obtaining the Fields data from the returned object
jint nRet = env->GetIntField(jobjRetData,env->GetFieldID(clsR,"returnValue","I"));
jstring jstrLog = (jstring)env->GetObjectField(jobjRetData,env->GetFieldID(clsR,"Log","Ljava/lang/String;"));
const char *pLog = env->GetStringUTFChars(jstrLog,0);

printf("\n\nValues Returned from Object are:\nreturnValue=%d\nLog=%s",nRet,pLog);
//After using the String type data release it.
env->ReleaseStringUTFChars(jstrLog,pLog);
}
//Release resources.
int n = jvm->DestroyJavaVM();
    return 0;
}

6. Output






















Comments

Post a Comment

Popular posts from this blog

Creating tray application and popup context menu in Windows

How to put an image to wxPanel using wxWidgets

How to build Xerces-c in Windows and Linux