sector
asked on
Combine Java with C
How can i combine c code ( as methods in an implementation of rmi serverimpl ) with Java ??
Can it be doen ??? how ??? how do i pass parameters
from java to c functions ???
Can it be doen ??? how ??? how do i pass parameters
from java to c functions ???
You didn't mention which platform or JDK version you are using so I'll note the most universal way of doing it. You define a method as "native". This tells Java that the underlying implementation of the function is not Java but implented in C (or some other language) on the hosting operating system. Check the documentation for your Java development environment on how to implement and use a native method.
To use a C program you have to use a Java Native Method. Basicly you have to defind the C program in Java, pass the varibles in vative types and recive the answers.
remember to generate the the C header not write it
p.s it is advisable to use C++ as it fits the OO programing
The only example i have is from Learn more java in 21 days so here goes
the pond example
pond.cpp------------------ -----
#include "Pond.h"
// Global field IDs
jfieldID fLengthID;
jfieldID fWidthID;
jfieldID fDepthID;
void JNICALL Java_Pond_initPond(JNIEnv* env, jclass thisClass) {
// Find the fields
fLengthID = env->GetFieldID(thisClass, "length", "F");
fWidthID = env->GetFieldID(thisClass, "width", "F");
fDepthID = env->GetFieldID(thisClass, "depth", "F");
}
jfloat JNICALL Java_Pond_getVolume(JNIEnv * env, jobject thisObject) {
// Get the field values
jfloat length = env->GetFloatField(thisObj ect, fLengthID);
jfloat width = env->GetFloatField(thisObj ect, fWidthID);
jfloat depth = env->GetFloatField(thisObj ect, fDepthID);
// Calculate and return the volume
return length * width * depth * 7.5f;
}
__________________________ __________ ___
pond.h-------------------- ---------- ---------- ---------- --------
* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Pond */
#ifndef _Included_Pond
#define _Included_Pond
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Pond
* Method: initPond
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_Pond_initPond
(JNIEnv *, jclass);
/*
* Class: Pond
* Method: getVolume
* Signature: ()F
*/
JNIEXPORT jfloat JNICALL Java_Pond_getVolume
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
-------------------------- ---------- ---------- ---------- -----
pond.java----------------- ---------- ---------- --------
import java.io.*;
public class Pond implements Serializable {
private float length, width, depth;
// Constructors
public Pond() {
this (0.0f, 0.0f, 0.0f);
}
public Pond(float l, float w, float d) {
length = l;
width = w;
depth = d;
}
// Accessor methods
public float getLength() {
return length;
}
public void setLength(float l) {
length = l;
}
public float getWidth() {
return width;
}
public void setWidth(float w) {
width = w;
}
public float getDepth() {
return depth;
}
public void setDepth(float d) {
depth = d;
}
// Natives
private static native void initPond();
public native float getVolume();
// Static startup code
static {
System.loadLibrary("Pond") ;
initPond();
}
}
-------------------------- ---------- ---------- ---------- ---------
pondTest.java------------- ---------- ---------- ---------- -
public class PondTest {
public static void main(String[] args) {
// Make sure we have the right number of args
if (args.length != 3) {
System.out.println("Usage: java PondTest Length Width Depth");
System.exit(0);
}
// Convert the args to floats
float length = Float.valueOf(args[0]).flo atValue();
float width = Float.valueOf(args[1]).flo atValue();
float depth = Float.valueOf(args[2]).flo atValue();
// Create the Pond object and display the volume in gallons
Pond pond = new Pond(length, width, depth);
System.out.println("Pond length = " + pond.getLength() + " feet");
System.out.println("Pond width = " + pond.getWidth() + " feet");
System.out.println("Pond depth = " + pond.getDepth() + " feet");
System.out.println("Pond volume = " + pond.getVolume() + " gallons");
}
}
-------------------------- ---------- ---------- ---------- ---
remember to generate the the C header not write it
p.s it is advisable to use C++ as it fits the OO programing
The only example i have is from Learn more java in 21 days so here goes
the pond example
pond.cpp------------------
#include "Pond.h"
// Global field IDs
jfieldID fLengthID;
jfieldID fWidthID;
jfieldID fDepthID;
void JNICALL Java_Pond_initPond(JNIEnv*
// Find the fields
fLengthID = env->GetFieldID(thisClass,
fWidthID = env->GetFieldID(thisClass,
fDepthID = env->GetFieldID(thisClass,
}
jfloat JNICALL Java_Pond_getVolume(JNIEnv
// Get the field values
jfloat length = env->GetFloatField(thisObj
jfloat width = env->GetFloatField(thisObj
jfloat depth = env->GetFloatField(thisObj
// Calculate and return the volume
return length * width * depth * 7.5f;
}
__________________________
pond.h--------------------
* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Pond */
#ifndef _Included_Pond
#define _Included_Pond
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Pond
* Method: initPond
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_Pond_initPond
(JNIEnv *, jclass);
/*
* Class: Pond
* Method: getVolume
* Signature: ()F
*/
JNIEXPORT jfloat JNICALL Java_Pond_getVolume
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
--------------------------
pond.java-----------------
import java.io.*;
public class Pond implements Serializable {
private float length, width, depth;
// Constructors
public Pond() {
this (0.0f, 0.0f, 0.0f);
}
public Pond(float l, float w, float d) {
length = l;
width = w;
depth = d;
}
// Accessor methods
public float getLength() {
return length;
}
public void setLength(float l) {
length = l;
}
public float getWidth() {
return width;
}
public void setWidth(float w) {
width = w;
}
public float getDepth() {
return depth;
}
public void setDepth(float d) {
depth = d;
}
// Natives
private static native void initPond();
public native float getVolume();
// Static startup code
static {
System.loadLibrary("Pond")
initPond();
}
}
--------------------------
pondTest.java-------------
public class PondTest {
public static void main(String[] args) {
// Make sure we have the right number of args
if (args.length != 3) {
System.out.println("Usage:
System.exit(0);
}
// Convert the args to floats
float length = Float.valueOf(args[0]).flo
float width = Float.valueOf(args[1]).flo
float depth = Float.valueOf(args[2]).flo
// Create the Pond object and display the volume in gallons
Pond pond = new Pond(length, width, depth);
System.out.println("Pond length = " + pond.getLength() + " feet");
System.out.println("Pond width = " + pond.getWidth() + " feet");
System.out.println("Pond depth = " + pond.getDepth() + " feet");
System.out.println("Pond volume = " + pond.getVolume() + " gallons");
}
}
--------------------------
the c++ program must be a DLL
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
This example will explain step-by-step the creation of an application use C native code. This example uses Sun's JNI 1.1. It will also demonstrate C if faster than Java by doing 500 000 calls to strlen and to
java.lang.String.length().
1.Create the Main.java file and compile it using javac Main.java
class Main
{
public static void main(String [] args)
{
CJava j=new CJava();
System.out.println(j.perfT
}
}
2.Create the CJava.java file and compile it using javac CJava.java
class CJava
static {
System.loadLibrary("CJava"
}
public int compute(String s) {
return s.length();
}
public native String perfTest(String s);
}
This class contains the definition for the perfTest method. It will be called by the main method to display a String. This class also loads the CJava.dll (Win32), or the CJava.so (Unix) dynamic library.
Note that the mapping from a library name to a specific filename is done in a system-specific manner.
The compute() method is used to return the string length to the native code. It would be faster to call directly the java.lang.String.length() method from native code, but the example would become less
clear.
3.Create the .h file using javah -jni CJava
This tool generate a header file with a .h extension contains the header for the perfTest C native method. You don't need to modify this file.
4.Create the CJava.cpp file and compile it.
#include <jni.h>
#include <stdio.h>
#include <string.h>
#include "CJava.h"
JNIEXPORT jstring JNICALL Java_CJava_perfTest(JNIEnv
{
char *buf=new char[100];
long a,i,j;
printf("Entering native method.\n\n");
const char *str=env->GetStringUTFChar
printf("The input string is: %s\n",str);
jclass cls = env->GetObjectClass(obj);
jmethodID mid = env->GetMethodID(cls, "compute", "(Ljava/lang/String;)I");
printf("Using C function to get the string length:\n");
for (a=1;a<500000;a++) j=strlen(str);
printf("C size: %d\n",j);
printf("Calling java method from native code to get the string length:\n");
for (a=1;a<500000;a++) i=env->CallIntMethod(obj, mid,s);
printf("Java size: %d\n",i);
printf("Creating the string returned by the function.\n");
sprintf(buf,"\nString %s :\nJava length=%d\nC length=%d\n",str,i,j);
env->ReleaseStringUTFChars
printf("Leaving native code.\n");
return env->NewStringUTF(buf);
}
To compile it on a win32 machine using Visual C++ , simply enter the command:
cl -I"C:\program files\javasoft\jdk1.1.4\in
5.Launch the main class using java Main
You should see a big performance difference between the first loop (using strlen() C function) and the other one (using java.lang.String.length())
code make this example unuseful.
Another site for interesting info on native methods
http://www.inside-java.com/articles/native/index.htm
http://www.inside-java.com/articles/native/index.htm