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 statically link applications to wxWidgets via Visual Studio 2008 and in Linux

How to put an image to wxPanel using wxWidgets