How to Access the Java Method in a C++ Application

How to access the Java method in a C++ application

Yes you can, but it is a little convoluted, and works in a reflective/non type safe way (example uses the C++ api which is a little cleaner than the C version). In this case it creates an instance of the Java VM from within the C code. If your native code is first being called from Java then there is no need to construct a VM instance

#include<jni.h>
#include<stdio.h>

int main(int argc, char** argv) {

JavaVM *vm;
JNIEnv *env;
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_2;
vm_args.nOptions = 0;
vm_args.ignoreUnrecognized = 1;

// Construct a VM
jint res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args);

// Construct a String
jstring jstr = env->NewStringUTF("Hello World");

// First get the class that contains the method you need to call
jclass clazz = env->FindClass("java/lang/String");

// Get the method that you want to call
jmethodID to_lower = env->GetMethodID(clazz, "toLowerCase",
"()Ljava/lang/String;");
// Call the method on the object
jobject result = env->CallObjectMethod(jstr, to_lower);

// Get a C-style string
const char* str = env->GetStringUTFChars((jstring) result, NULL);

printf("%s\n", str);

// Clean up
env->ReleaseStringUTFChars(jstr, str);

// Shutdown the VM.
vm->DestroyJavaVM();
}

To compile (on Ubuntu):

g++ -I/usr/lib/jvm/java-6-sun/include \ 
-I/usr/lib/jvm/java-6-sun/include/linux \
-L/usr/lib/jvm/java-6-sun/jre/lib/i386/server/ -ljvm jnitest.cc

Note: that the return code from each of these methods should be checked in order to implement correct error handling (I've ignored this for convenience). E.g.

str = env->GetStringUTFChars(jstr, NULL);
if (str == NULL) {
return; /* out of memory */
}

How to call C# function from java

First of all lets create a C# file like this:

using System;
public class Test{
public Test(){}
public String ping(){
return "C# is here.";
}
}

Then compile this with command below:

csc.exe /target:module Test.cs  

You can find csc.exe in install path of .NET framework. After that create java file:

public class Test{
public native String ping();
public static void main(String[] args){
System.load("/path/to/dll");
System.out.println("Java is running.");
Test t = new Test();
System.out.println("Trying to catch C# " + r.ping());
}
}

javac Test.java This generates a Test.class.

javah -jni Test This generates a Test.h file which will be included in
C++ code.

After that we need to create our C++ file:

#include "stdafx.h"
#include "JAVA/Test.h"
#include "MCPP/Test.h"
#pragma once
#using <mscorlib.dll>
#using "Test.netmodule"
JNIEXPORT jstring JNICALL Java_Test_ping(JNIEnv *env, jobject obj){
Test^ t = gcnew Test();
String^ ping = t->ping();
char* str = static_cast<char*>((System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(ping)).ToPointer());

char cap[128];
strcpy_s(cap, str);

return env->NewStringUTF(cap);
}

Finally:

c:\>java Test

I hope this helps you. A basic example to use function C# in Java.

Sources:
https://www.quora.com/How-common-is-the-problem-of-calling-C-methods-from-Java-Do-many-developers-come-across-such-necessity

Call Java method from .Net

IKVM is pretty heavyweight (not to mention discontinued) so if you can avoid it then it might be easier.

If the Java program can produce its output on STDOUT (i.e. write to the console) then you could read that output via your Process object.

For example:

Process myProcess = new Process();
Process.StartInfo.UseShellExecute = false;
myProcess.StartInfo.FileName = "java";
myProcess.StartInfo.Arguments = "-jar D:\\myjava.jar";
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.Start();
var output = process.StandardOutput.ReadToEnd();

You may need to experiment with setting other properties on your ProcessStartInfo.

Call Java function using .Net(C#)

If you want to communicate between C# and Java you have a couple of options.

The cleanest: Build a service.

This assumes you have access to the source code of both your C# component and your Java component. In the case that you want to call a method within Java, you can build a service that allows a connection from your C# client, to your Java service, and the service then executes the desired functionality, and returns a value back to the C# client. Some easy ways to do this is by building a RESTful service or using Thrift. I recommend you choose a solution similar to this one.

The most complex: Corba

Corba is a standard defined to communicate amongst different computer languages. Most mature languages have support for it, but it is a bit unusual, and the use of it has declined in favor of building service. This also assumes access to both source codes.
You'd have to independently look for the information regarding how to use Corba on both Java and C#. I would really advice against this.

The dirtiest but quickest: Execute as process and parse output

I really do NOT recommend you to do it this way unless you really have no choice. This would entail executing a Java program from within C#. This is only a good choice when you have no other option, because all you have is an executable. If that were the case, you can use the Process class to execute the external program, sending it parameters, and then reading the output. See the example mentioned here:
How do I start a process from C#?

This has many downsides though, as you'll have to think of every exceptional cause, determine the output for those cases, and then determine how to parse that output. If the program has any level of complexity, before you know it, you'll end up with hard to maintain code.

Conclusion: Build a Service

That's probably your best bet. Build a service that exposes an API that the C# client can call on.

Call any Java method from C#

IKVM is one option. It implements a JVM in .Net and provides interop tools.

Call Java Method from API in .NET

Here you go :) I've used it myself and was very please with the implementation.

IKVM: Using Java API's in .NET Applications

  • (1) If you just want some libraries
    from Java.

  • (2.1) If you have access to
    the code.

  • (2.2) Last resort,
    dynamically load the Java into .Net
    (interpreter)



Related Topics



Leave a reply



Submit