Java calls C + + dynamic-link library using JNI

Source: Internet
Author: User

Java calls C + + dynamic-link library using JNI

Use JNI to connect DLL dynamic-link libraries and invoke functions in them

First C + + write good correlation function, file name is test.cpp, use g++ compile as DLL file, instruction is as follows:

g++-shared-wl,--kill-at,--output-def,test.def-o test.dll test. CPP

This creates both the Test.def and Test.dll files at the same time as the path.

By the way,. lib files can be generated with a. def file, and the build method is in VS

Lib/def:xxx.def/machine:x86 (or X64) command

After getting the. dll file, Java can theoretically use JNI to invoke the

 Public classJNIDemo1 { Public Static native  Shortconnectcnc (String IP);  Public Static native voidWriteData (); Static{system.loadlibrary ("Melwin"); System.loadlibrary ("Melcfg"); System.loadlibrary ("Melsmem"); System.loadlibrary ("Chgapivl"); System.loadlibrary ("Meldev"); System.loadlibrary ("Melmdldr"); System.loadlibrary ("MELVNCKD"); System.loadlibrary ("Ncmocha"); System.loadlibrary ("Nccom"); System.loadlibrary ("NCAPI32"); System.loadlibrary ("Test"); }//The system will determine its own suffix.       Public Static voidMain (string[] args) { ShortRES=CONNECTCNC ("192.168.200.1"); if(res==0) {System.out.println ("Connect success!\tdata writing...\n");        WriteData (); }Else{System.out.println ("Connect Fail.code:" +res); }    }} 

Two native function is a C + + function to invoke

You need to use the native keyword in the main class to define it beforehand

Load lib file suffix do not describe, let Java according to the OS platform to judge itself

The command to load Lib has a sequential order, so be sure to write the order of command in the call hierarchy.

If you do not know the order of calls between DLLs, you can download the DLL dependent view tool to parse the DLL

Error when loading DLL no test in Java.library.path

The reason is that JNI cannot find where your DLL file is, so adjust the Eclipse Project project's Build Path

Modify the native library location in the JDK to point to your DLL path, as follows:

If the g++ of the compiled DLL is 64-bit and the JDK is 32-bit, an error will be

Can ' t load AMD 64-bit. dll on a IA 32-bit platform

The reverse will be error

Can ' t load IA 32-bit. dll on a AMD 64-bit platform

In this case, there is no need to attempt to replace the g++ compiler because the external DLLs that are referenced are mostly 32-bit

And our JDK can install both 32-bit and 64-bit, which does not conflict in the system

So you should go to download the corresponding schema to recompile the Java file to execute the JDK

After compiling the Java file, do not rush to run, and some work to go back to C + + to complete

Compile to get the. class file, General Eclipse save a good. class file with no syntax errors

cmd to the SRC root directory, use the Javah command to generate the. h header file, or you can write the. h header directly, in the following format:

/*Do not EDIT this file-it are machine generated*/#include<jni.h>/*Header for Class Com_saiyang_newflypig_jnidemo_jnidemo1*/#ifndef _included_com_saiyang_newflypig_jnidemo_jnidemo1#define_included_com_saiyang_newflypig_jnidemo_jnidemo1#ifdef __cplusplusextern "C" {#endif/** CLASS:COM_SAIYANG_NEWFLYPIG_JNIDEMO_JNIDEMO1 * METHOD:CONNECTCNC * Signature: (ljava/lang/string;) S*/jniexport jshort jnicall java_com_saiyang_newflypig_jnidemo_jnidemo1_connectcnc (JNIEnv*, Jclass, jstring); Jniexportvoidjnicall java_com_saiyang_newflypig_jnidemo_jnidemo1_writedata (jnienv*, Jclass); #ifdef __cplusplus}#endif#endif

Function name don't be mistaken, JNI is going to look for the relevant function through these specifications.

You can call the functions of any other pure format that you write directly in the canonical function

The. h header file has a natural need to modify the CPP file:

#defineBuild_mit_dll#include<stdio.h>#include<string>#include"melncapi.h"#include"ncmcapi.h"#include"melsect.h"#include"melssect.h"#include"meltype.h"#include"test.h" using namespacestd;voidReadData ();voidWriteData (); ShortCONNECTCNC (string);Char* Jstring2char (jnienv*, jstring); intMain () {DWORD res=CONNECTCNC ("192.168.200.1"); if(Res! =0) {printf ("fail...code:%d\n", RES); }    Else{printf ("Connect success!\n");    WriteData (); }     return 0;}  ShortCONNECTCNC (stringIP)    {Meldevicedata melioctldata; DWORD dwstatus=0; MelIoctlData.uniDeviceInfo.Tcp.lPortNo=683; memset (MELIOCTLDATA.UNIDEVICEINFO.TCP.IPADDR,0, -);    strcpy (MelIoctlData.uniDeviceInfo.Tcp.IPAddr, Ip.data ()); Melioctldata.dwdevicetype=devicetype_tcp; //long oldtimeout = 0, TimeOut = 2; //dwstatus = Melioctl (NULL, Adr_machine (1), dev_get_commtimeout, &oldtimeout); //if (dwstatus = = 0)//Melioctl (NULL, Adr_machine (1), dev_set_commtimeout, &timeout);Dwstatus = Melioctl (NULL, Adr_machine (1), Dev_set_commaddress, &melioctldata); returnDwstatus;} voidReadData () {//long lsectionnum = M_sec_plc_dev_word; //m_sec_plc_dev_bit, M_sec_plc_dev_char, M_sec_plc_dev_word    LongLsectionnum =M_sec_plc_dev_bit; LongLaddress = Adr_machine (1); LongLaxisflag =0;  ShortLgetdata =0;  Shorty=0;  while(SCANF ("%d", &y), y!=-1){        LongLsubsectionnum =M_ssec_pllng_y_1shot (Y); DWORD dwstatus= Melgetdata (NULL, laddress, Lsectionnum, Lsubsectionnum, Laxisflag, &Lgetdata, T_long); printf ("%d\n", Lgetdata); }} voidWriteData () {LongLsectionnum =M_sec_plc_dev_bit; LongLaddress = Adr_machine (1); LongLaxisflag =0;  ShortLsetdata;  ShortXnum;  while(SCANF ("%d", &xnum), xnum!=-1) {scanf ("%d",&lsetdata); LongLsubsectionnum =M_ssec_pllng_x_1shot (Xnum); DWORD dwstatus= Melsetdata (NULL, laddress, Lsectionnum, Lsubsectionnum, Laxisflag, &Lsetdata, T_long); if(Dwstatus = =0) {printf ("Write success!\n"); }Else{printf ("Write fail!code:%d\n", dwstatus); }}} Jniexport jshort jnicall java_com_saiyang_newflypig_jnidemo_jnidemo1_connectcnc (JNIEnv*env, Jclass, jstring IP) {    returnCONNECTCNC (Jstring2char (ENV,IP));} JniexportvoidJnicall Java_com_saiyang_newflypig_jnidemo_jnidemo1_writedata (JNIENV *, Jclass) {WriteData ();} /** * Return value char* This represents the first address of the char array * JSTRING2CSTR converts the type of jstring in Java into a char string in the C language*///jstring to char*Char* Jstring2char (jnienv*env, jstring jstr) {     Char* Rtn =NULL; Jclass clsstring= Env->findclass ("java/lang/string"); Jstring Strencode= Env->newstringutf ("Utf-8"); Jmethodid Mid= Env->getmethodid (clsstring,"getBytes","(ljava/lang/string;) [B"); Jbytearray Barr= (Jbytearray) env->Callobjectmethod (Jstr, Mid, Strencode); Jsize Alen= env->Getarraylength (Barr); Jbyte* ba = env->getbytearrayelements (Barr, Jni_false); if(Alen >0) {Rtn= (Char*)malloc(Alen +1);         memcpy (RTN, BA, Alen); Rtn[alen]=0; } env->releasebytearrayelements (Barr, BA,0); returnRtn;}

That's it, remember that we started the g++ command to compile the DLL?

Once again, after generating the. dll, execute the Java program and you should be able to invoke it.

Java calls C + + dynamic-link library using JNI

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.