Wednesday, December 2, 2009

Java Native Interface

Here is an example for Java Native Interface
Java application that calls a C function and executes the operation.
Example
Ping program
Step1:
           Write a java program for ping operation.
import java.util.StringTokenizer;



public class PINGMain {




String ipaddress = null;




boolean defragment = false;




int num = 2;




String str = "www.yahoo.com";




String success ="success";




String[] ipaddr = { "www.yahoo.com", "20", "2000", "5000", "500" };




private String destination;




private String packetSize;




private String bytes;




private String time;




        private String ttl;




protected native String ping(String[] ipaddress);




public PINGMain() {




super();




try {




System.loadLibrary("ping");




} catch (UnsatisfiedLinkError e) {




e.printStackTrace();




}




singlePing();




}




private void singlePing() {




int a = 10;




int b = 20;




String string=null;




while(true) {




string = ping(ipaddr);




//System.out.println(string);




StringTokenizer strToken = new StringTokenizer(string);




int numToken = strToken.countTokens();




            destination =   strToken.nextToken();




            bytes = strToken.nextToken();




            time=       strToken.nextToken();




            ttl = strToken.nextToken();




System.out.println("\n Reply from"+" "+destination+" "+"bytes"+" "+bytes+" "+"Time"+" "+time+" "+"TTL"+" "+ttl);




}




}




private String continuousPing() {




return null;




}




private String disconnect() {




//unLoadPing();




//System.out.println("Unloaded SuccessFully");




return success;




}




private void unLoadPing() {




// unLoad();




}




/**




* @return




*/




private String getStatistics() {




return null;




}




public static void main(String ar[]) {




new PINGMain();




}




}






 



Step 2:





   Using javac to compile the PINGMain source file




After you have defined the PINGMain class, save the source code in a file called PINGMain .java. Then compile the source file using the javac compiler as follows:




javac PINGMain.java
This command will generate a PINGMain.class file in the current directory.


Step 3:




Using javah -jni to generate a C header file (PINGMain.h) containing the function prototype for the native method implementation

Next we will use the javah tool to generate a JNI-style header file that is useful when implementing the native method in C. You can run javah on the PINGMain class as follows:





  • javah -jni PINGMain

    The command shown above generates a file named PINGMain.h.






  • Step 4:





    Writing the C implementation (PINGMain.c) of the native method





    The JNI-style header file generated by javah helps you to write C or C++ implementations for the native method. The function that you write must follow the -prototype specified in the generated header file.












    #pragma comment(lib, "wsock32.lib")


    #include "jni.h"


    #include "com_dtt_traffic_ping_PINGMain.h"


    #include "stdlib.h"


    #include "StdAfx.h"


    #include <windows.h>


    #include <winsock.h>


    #include <stdio.h>


    #include <string.h>





    int packetsize;

    int count;


    char *data;//Ping info


    typedef struct tagIPINFO


    {


            u_char Ttl;                             // Time To Live


            u_char Tos;                             // Type Of Service


            u_char IPFlags;                 // IP flags


            u_char OptSize;                 // Size of options data


            u_char FAR *Options;    // Options data buffer


    }IPINFO, *PIPINFO;





    typedef struct tagICMPECHO

    {


            u_long Source;                  // Source address


            u_long Status;                  // IP status


            u_long RTTime;                  // Round trip time in milliseconds


            u_short DataSize;               // Reply data size


            u_short Reserved;               // Unknown


            void FAR *pData;                // Reply data buffer


            IPINFO  ipInfo;                 // Reply options


    }ICMPECHO, *PICMPECHO;





    // ICMP.DLL Export Function Pointers

    HANDLE (WINAPI *pIcmpCreateFile)(VOID);


    BOOL (WINAPI *pIcmpCloseHandle)(HANDLE);


    DWORD (WINAPI *pIcmpSendEcho)


            (HANDLE,DWORD,LPVOID,WORD,PIPINFO,LPVOID,DWORD,DWORD);





    //

    //


    char *pingFun(char *dest[])


    {


        int timeout;


        char ping_Resp[2048];


            WSADATA wsaData;                        // WSADATA


            ICMPECHO icmpEcho;                      // ICMP Echo reply buffer


            HANDLE hndlIcmp;                        // LoadLibrary() handle to ICMP.DLL


            HANDLE hndlFile;                        // Handle for IcmpCreateFile()


            LPHOSTENT pHost;                    // Pointer to host entry structure


            struct in_addr iaDest;              // Internet address structure


            DWORD *dwAddress;                       // IP Address


            IPINFO ipInfo;                          // IP Options structure


            int nRet;                                       // General use return code


            DWORD dwRet;                            // DWORD return code


            int x;





           packetsize = atoi(dest[2]);

            count = atoi(dest[5]);


            timeout = atoi(dest[4]);


            // Dynamically load the ICMP.DLL


            hndlIcmp = LoadLibrary("ICMP.DLL");


            if (hndlIcmp == NULL)


            {


                    fprintf(stderr,"nCould not load ICMP.DLLn");


                    return;


            }


            // Retrieve ICMP function pointers


            pIcmpCreateFile = (HANDLE (WINAPI *)(void))


                    GetProcAddress(hndlIcmp,"IcmpCreateFile");


            pIcmpCloseHandle = (BOOL (WINAPI *)(HANDLE))


                    GetProcAddress(hndlIcmp,"IcmpCloseHandle");


            pIcmpSendEcho = (DWORD (WINAPI *)


                    (HANDLE,DWORD,LPVOID,WORD,PIPINFO,LPVOID,DWORD,DWORD))


                    GetProcAddress(hndlIcmp,"IcmpSendEcho");


            // Check all the function pointers


            if (pIcmpCreateFile == NULL             ||


                    pIcmpCloseHandle == NULL        ||


                    pIcmpSendEcho == NULL)


            {


                    fprintf(stderr,"nError getting ICMP proc addressn");


                    FreeLibrary(hndlIcmp);


                    return;


            }





            // Init WinSock

            nRet = WSAStartup(0x0101, &wsaData );


        if (nRet)


        {


            fprintf(stderr,"nWSAStartup() error: %dn", nRet);


            WSACleanup();


                    FreeLibrary(hndlIcmp);


            return;


        }


        // Check WinSock version


        if (0x0101 != wsaData.wVersion)


        {


            fprintf(stderr,"nWinSock version 1.1 not supportedn");


            WSACleanup();


                    FreeLibrary(hndlIcmp);


            return;


        }





            // Lookup destination

        // Use inet_addr() to determine if we're dealing with a name


        // or an address


        iaDest.s_addr = inet_addr(dest[1]);


        if (iaDest.s_addr == INADDR_NONE)


            pHost = gethostbyname(dest[1]);


        else


            pHost = gethostbyaddr((const char *)&iaDest,


                            sizeof(struct in_addr), AF_INET);


            if (pHost == NULL)


            {


                    fprintf(stderr, "n%s not foundn", dest[1]);


            WSACleanup();


                    FreeLibrary(hndlIcmp);


                    return;


            }





            // Tell the user what we're doing

            /*printf("nPinging %s [%s]", pHost->h_name,


                            inet_ntoa((*(LPIN_ADDR)pHost->h_addr_list[0])));*/





            // Copy the IP address

            dwAddress = (DWORD *)(*pHost->h_addr_list);





            // Get an ICMP echo request handle

            hndlFile = pIcmpCreateFile();


           // for (x = 0; x < 4; x++)


                    // Set some reasonable default values


                    ipInfo.Ttl =dest[3];


                    ipInfo.Tos = 0;


                    ipInfo.IPFlags = 0;


                    ipInfo.OptSize = 0;


                    ipInfo.Options = NULL;


                    //icmpEcho.ipInfo.Ttl = 256;


                    // Reqest an ICMP echo


                    dwRet = pIcmpSendEcho(


                            hndlFile,               // Handle from IcmpCreateFile()


                            *dwAddress,             // Destination IP address


                            packetsize,                   // Pointer to buffer to send


                            0,                              // Size of buffer in bytes


                            &ipInfo,                // Request options


                            &icmpEcho,              // Reply buffer


                            sizeof(struct tagICMPECHO),


                            timeout);                  // Time to wait in milliseconds


                    // Print the results


                    iaDest.s_addr = icmpEcho.Source;


                   /* printf("\n Reply from %s  Time=%ldms  TTL=%d",


                                    inet_ntoa(iaDest),


                                    icmpEcho.RTTime,


                                    icmpEcho.ipInfo.Ttl);*/


                    sprintf(ping_Resp,"%s %d %ld %d",    
                    inet_ntoa(iaDest),


                    packetsize,


                    icmpEcho.RTTime,


                    icmpEcho.ipInfo.Ttl);


                    if (icmpEcho.Status)


                    {


                           // printf("nError: icmpEcho.Status=%ld",


                            //        icmpEcho.Status);


                            printf("\n Request timed out");


                            //break;


                    }


            //printf("\n");


            // Close the echo request file handle


            pIcmpCloseHandle(hndlFile);


            FreeLibrary(hndlIcmp);


            WSACleanup();


            return ping_Resp;


    }


    JNIEXPORT jstring JNICALL Java_com_dtt_traffic_ping_PINGMain_ping


       (JNIEnv *env, jclass job, jobjectArray oarr)


    {


       jsize argc = (*env)->GetArrayLength(env, oarr);





       /* Declare a char array for argv */

       int i;


       char const* argv[128];





       for (i = 1; i < 6; i++)

       {


          /* obtain the current object from the object array */


          jobject myObject = (*env)->GetObjectArrayElement(env, oarr, i-1);





          /* Convert the object just obtained into a String */

          const char *str = (*env)->GetStringUTFChars(env,myObject,0);


          /* Build the argv array */


          argv[i] = str;


      }


         data=(char *)malloc(sizeof(char) * 2048);


         sprintf(data,"%s",pingFun(argv),"-10000");


        // printf("Data %s ",data);


          return ((*env)->NewStringUTF(env,data));












    }












    Step5:




            Compiling the C implementation into a native library, creating ping.dll or libPINGMain.so





    On Solaris or Linux, the following command builds a shared library called libPINGMain.so:


    cc -G -I/java/include -I/java/include/solaris

    PINGMain.c -o libPINGMain.so


    On Win32, the following command builds a dynamic link library (DLL) ping.dll using the Microsoft Visual C++ compiler:



  • cl -Ic:\java\include -Ic:\java\include\win32

    -MD -LD PINGMain.c -ping.dll


    Step 6: Running the PINGMain.java



    java PINGMain




        If you get the following error put the dll file in the java path


    java.lang.UnsatisfiedLinkError: no PINGMain in library path

    at java.lang.Runtime.loadLibrary(Runtime.java)


    at java.lang.System.loadLibrary(System.java)


    at PINGMain .main(PINGMain.java)

    0 Comments:

    Post a Comment

    The Link Exchange - Your ultimate resource for link exchange!

    About This Blog

      © Blogger template Webnolia by Ourblogtemplates.com 2009

    Back to TOP