How to call a C program from Java?


Calling a C program may be useful when we prefer to use C libraries and to reuse an existing C program. When we compile a C program, the source gets converted to obj file. It is a platform dependent intermediate machine code which will be converted to exe and then executed.
Java native interface (JNI) is a framework provided by java that enables java programs to call native code and vice-versa.

Using JNI a java program has the capability to call the native C code. But we lose the core objective of java which is platform independence. So calling a C program from java should be used judiciously.
JNI provides the specification and native code should be written/ported accordingly. JDK vendor should provide the needed implementation for the JNI.

Steps to call a C program from Java

1. Write the Java Program and Compile
2. Generate header file from java class
3. Write the C Program
4. Generate Shared Library File
5. Run Java Program

1. Write the Java Program

public class JavaToC {
    public native void helloC();
    static {
        System.loadLibrary("HelloWorld");
    }
    public static void main(String[] args) {
        new JavaToC().helloC();
    }
}

Note two things in this program,

  1. Use of native keyword. This is a method declaration and it informs the java compiler that the implementation for this method is a native one. This method helloC() is present in C source file and that is what we are going to call.
  2. Loading the library HelloWorld using static keyword. This library file will be compiled out of the C source in the coming steps.

2. Generate header file from java class


  1. JDK provides a tool named javah which can be used to generate the header file.
  2. We will use the generated header file as include in C source.
  3. Remember to compile the java program before using javah

javah JavaToC
Following is the header file generated,


/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JavaToC */

#ifndef _Included_JavaToC
#define _Included_JavaToC
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JavaToC
 * Method:    helloC
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_JavaToC_helloC
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif


3. Write the C Program

#include <stdio.h>
#include <jni.h>
#include "JavaToC.h"
JNIEXPORT void JNICALL Java_JavaToC_helloC(JNIEnv *env, jobject javaobj)
{
  printf("Hello World: From C");
  return;
}

  1. stdio.h is the standard C header file include.
  2. jni.h is the header file that provides the java to C mapping and it is available in JDK.
  3. JavaToC.h is the header file generated from the java source file.

4. Generate Shared Library File

  1. Now compile the above C source file. We need a C compiler and I have chosen Tiny C.
  2. Tiny C can be downloaded from http://mirror.veriportal.com/savannah//tinycc/tcc-0.9.25-win32-bin.zip
  3. Download and unzip the file and set OS path to tcc.exe
  4. tcc HelloWorld.C -I C:/Progra~1/Java/jdk1.7.0_07/include -I C:/Progra~1/Java/jdk1.7.0_07/include/win32 -shared -o HelloWorld.dll
  5. Above is the command to generate the shared library file dll which is loaded in the java program. Two directories are included in the compile command, those are to include the jni.h and jni_md.h

5. Run Java Program

We are all set, now run the java program to get the following output,
Hello World: From C




1 comments:

how can we store Function in pointer


So far u have seen that a pointer stores address of variable, array, structure n many else. But there is one another property of a pointer to store or to refer a complete function, i.e., a pointer is referring a function and then this pointer can be used simply as we use our function.

An example for this is as:

#include<iostream>
#include<conio.h>

using namespace std;
int fun()
{
     cout<<"Enigma of C++";
}

main()
{
      int (*p)() =fun;   //Here the pointer p can now be used in place of function fun
      (*p)();                //This is the way how this pointer can be used
      getch();
}

Another example by using a parameterized function (function with arguments) can be:

#include<iostream>
#include<conio.h>

using namespace std;
int fun(int a,int b)
{
    if(a>b)
      return a;
    return b;
}

main()
{
      int(*p)(int,int) =fun;           //see how the pointer is declared  
      int d= (*p)(4,3);                   //value returned by the function is stored in d;    
      cout<<d;
      getch();
}

Points to remember:

1.        Always keep in mind that at the time of declaration of the pointer its type should same as the return type of the function. This means that if the return type of the function is int then the pointer is declared as :
int (*p)()
If function has a void data type then pointer will be declared as:
void (*p)()
2.       Before the declaration of pointer the function must be declared once in the scope of pointer
Consider this example:
#include<iostream>
#include<conio.h>

using namespace std;
main()
{
      int(*p)()=fun;
      (*p)();
      getch();
}
int fun()
{
     cout<<"Enigma of C++";
}
The above code will generate an error of function not defined.
To correct the program include the declaration of function as int fun (); before the declaration of the pointer.

1 comments:

how can we use WATCH in Turbo C

Logical errors are one of the frequent errors appearing in our programs. They are those that make us so embarrass that our code is completely correct with no errors still not getting correct output..!!
But turbo c provides an application called WATCH which could help us to tackle these errors. The complete operation is presented in the video.



0 comments:

c using namespace std


Namespaces allow to group entities like classes, variables and functions under a name. This way the global scope can be divided in "sub-scopes", each one with its own name. Some cases where absence of namespaces leads to error  -:

--> if your program defined a function called abs( ), it could override the standard library function
abs( ) because both names would be stored in the global namespace ( global namespace is your complete program ).

--> if your program defines a class call ThreeDCircle and a library used by your program defines a class by the same name, a conflict will arise.

The creation of the namespace keyword was a response to these problems. Because it localizes the visibility of names declared within it, a namespace allows the same name to be used in different contexts without conflicts arising. This means that we can use variables, classes, functions of same names in our program

Syntax

namespace name
{
  // declarations
}

A simple example for namespace is as :

namespace sample
{
  int a, b;
}

Simple program to use it is:

#include <iostream>
using namespace std;    // This line is completely explained at the end of this post
namespace sample
{
  int a, b;
}
int main ()                                                                                                                                                          
{
  sample::a=3;    //See here we have to use a scope operator to access the variables
  sample::b=5;
  cout <<sample::a<< endl;
  cout <<sample::b<< endl;
  return 0;
}

Functionality of namespaces is especially useful in the case that there is a possibility that a global object/variable or function uses the same identifier as another one, causing redefinition errors. This problem is resolved in the code below where the variable var is defined twise in th same global namespace :

#include<conio.h>
#include <iostream>
using namespace std;
namespace samplefirst
{
  int var = 5;
}
namespace samplesecond
{
  double var = 3.1416;
}
int main ()
{
  cout << samplefirst::var << endl;
  cout << samplesecond::var << endl;
  getch();
  return 0;
}

In this case, there are two global variables with the same name: var but now they are not same as they are defined in different namespaces and no ERRORS.

using :

In above example we were using the name of namespace and the scope operator each time we want to use its attributes. The using statement was invented to alleviate this problem. The using statement has these two general forms:

using namespace name;   // the complete namespace is brought into view in the current                
                                               namespace/block

using name::member;     //only a single member of the namespace is introduced in the current namespace/block

Above example with using keyword
#include <iostream>
using namespace std;
namespace sample
{
  int a, b;
}
int main ()
{
  using namespace sample;
  a=3;   
  b=5;
  cout <<a<< endl;
  cout <<b<< endl;
  return 0;
}
Now comes the most awaited topic for which this post has been created :

The std Namespace

Standard C++ defines its entire library in its own namespace called std. This is the reason that most of the programs we see in many books and on internet include the following statement:
using namespace std;

The above statement causes the std namespace to be brought into the current namespace, which gives
you direct access to the names of the functions and classes defined within the library/std namespace

You might see some statements in many books as
std::cout
std::cin

this is nothing but using attributes or functions in the std namespace explicitly 

Here is a simple example in 2 different ways

#include <iostream>
int main()
{
  int val;
  std::cout << "Enter a number: ";
  std::cin >> val;
  std::cout << "This is your number: ";
  std::cout << std::hex << val;
  return 0;
}

And the other one is :

#include <iostream>
using namespace std;
int main()
{
  int val;
  cout << "Enter a number: ";
  cin >> val;
  cout << "This is your number: ";
  cout << hex << val;       //hex is used to print the hexadecimal value of integer
  return 0;
}


2 comments:

Functions with return type returning no values

An interesting thing about a functions in C++ with a non-void return type is that if you forget to place a return statement at the end of your function the it automatically return the ""result of last arithmetic operation"" done in that function code or else a 0 in normal functions and a garbage value if the function is inside a class
For eg-:

#include <iostream>

#include<conio.h>
using namespace std;

int fun()
{
    int i = 34 ;
    int j = i + 1 ;     //no return type mentioned here still output is 35
}

int main()
{
    cout << fun();  //output is 35
    getch();
    return 0;
}

another example where the line j = i + 1 is missing


#include <iostream>

#include<conio.h>
using namespace std;

int fun()
{
    int i = 34 ;
  //  int j = i + 1 ;  
}

int main()
{
    cout << fun();   // output is 0
    getch();
    return 0;
}






3 comments:

MYSELF

Hey guys am here to provide u some tricks related to C,C++ and java which might be helpful to many of the programmers out there which are embarrassed by solving the enigma of languages...
So here i start by showing u a small trick to just tease your friend...

0 comments:

Template by Clairvo Yance
Copyright © 2012 Enigma of IT and Blogger Themes.