Java calls third-party DLL

Source: Internet
Author: User

Recently, due to the need for graduation design, we use J2EE to create an Experiment Reservation System, which involves a card reader and an IC card reader, to get a card reader, the vendor only provides one Windows dynamic link library written in C. smartcom411sfj. DLL, I need to use a Java program to call this DLL file to obtain information in the card. In fact, the functions I use are very simple. There are three functions:

Serial Port initialization function: int inicom (INT comport, int baudrate)

Card reading information function: int readpersonalinfo (INT comport, unsigned char * Name, unsigned char * buffer)

Disable the serial port function: int closecom (INT comport)

I checked a lot of information on the Internet and learned that JNI can be used to call local DLL files. many friends on the Internet asked similar questions. However, after reading the answers from many netizens, I still cannot solve my own problems, many of the answers are to copy some code from someone else's webpage, without telling how to call a third-party DLL file. Opening many webpages found that the content is the same, there are even a lot of codes that are incorrect, and there is no answer to the questioner's question at all. It is difficult to find a solution.

I started to try the following methods on the Internet:

1. Write a class in Java, use the system. loadlibrary method to call the dynamic link library, and declare each method in the dynamic link library.

2. Then, use javac to compile the class file and then use javah to generate a. h file.

3. Compile a C/C ++ program to generate a DLL file that can be directly called by Java.

4. Place the generated DLL file in a Java file and re-run the Java program.

But the problem is that many data types used in C cannot be used in Java, such as unsigned char * and handle. How can we convert them? I think this is very common. Why do few people answer this question? Maybe my search capability is too poor, huh, huh!

After several days of hard work, I finally solved the problem. I listed a write problem encountered during the compilation process. Although my program is a bit simple, I 'd like to share it with you, I hope my friends who are just as confused can use it.

1. in the Java program, first declare the name of the library to be called by Java. You do not need to write the extension name of the Library. The name of the library is not provided by the merchant, it is best not to use the same name as the library provided by the merchant, otherwise errors may occur. You also need to make a local Declaration on the method to be called and use the keyword native. You only need to declare that the method name and parameter do not need to be the same as the method in the library provided by the merchant, besides, some C parameter types cannot be expressed in Java. For example, the content of my program smartcard. Java is as follows:

Public class smartcard {

Static {

System. loadlibrary ("smartcard"); // a library that can be directly called using Java written in C/C ++

}

 

// The local method declaration needed in Java. It is best to set it as private in terms of security.

Private native int inicom (INT comport, int baudrate );

Private native int closecom (INT comport );

Private native string readpersonalinfo (INT comport );

 

// Methods that can be called by external classes

Public int inicomtemp (INT comport, int baudrate ){

Return this. inicom (comport, baudrate );

}

Public int closecomtemp (INT comport ){

Return this. closecom (comport );

}

Public String readpersonalinfotemp (INT comport ){

Return this. readpersonalinfo (comport );

}

}

2. compile and generate the class file using javac smartcard, and then call javah SmartCard to generate the C/C ++ header file.

For example, the. h file generated by my program is as follows:

/* Do not edit this file-it is machine generated */

# Include <JNI. h>

/* Header for class smartcard */

 

# Ifndef _ included_smartcard

# DEFINE _ included_smartcard

# Ifdef _ cplusplus

Extern "C "{

# Endif

/*

* Class: smartcard

* Method: inicom

* Signature: (ii) I

*/

Jniexport jint jnicall java_smartcard_inicom

(Jnienv *, jobject, jint, jint );

 

/*

* Class: smartcard

* Method: closecom

* Signature: (I) I

*/

Jniexport jint jnicall java_smartcard_closecom

(Jnienv *, jobject, jint );

 

/*

* Class: smartcard

* Method: readpersonalinfo

* Signature: (I) ljava/lang/string;

*/

Jniexport jstring jnicall java_smartcard_readpersonalinfo

(Jnienv *, jobject, jint );

 

# Ifdef _ cplusplus

}

# Endif

# Endif

3. in C/C ++, for the generated. what C/C ++ needs to do is to implement each of its methods and connect them to the library file, the third-party DLL files provided by the merchant and the conversion data types are required in the implementation process. To write the code, you need to compile the generated one. add the H file to the header file, and add the JNI under the include folder in JDK. H and jni_md.h under include/Win32 are added to include in the compiler, or if the source files are put together, the system will prompt that JNI cannot be found. This is what you can generate using javah. <JNI. h> change to "JNI. H ". Type conversion and how to call the library provided by the merchant to analyze the code. Note that the DLL file used here cannot be the same as the DLL file used in Java.

# Include "stdafx. H"

# Include "windows. H"

# Include "string. H"

# Include "smartcard. H" // This header file must be included

 

Typedef int (_ stdcall * inicom) (INT comport, int baudrate); // The parameter must be consistent with the method parameters in the DLL file provided by the merchant

Typedef int (_ stdcall * closecom) (INT comport );

Typedef int (_ stdcall * idread) (INT comport, unsigned char * Name, unsigned char * buffer );

 

Hinstance dllhandle;

Int result;

// Initialize the serial port

Jniexport jint jnicall java_smartcard_inicom (jnienv * ENV, jobject Jo, jint comport, jint baudrate ){

Inicom pinicom;

Dllhandle = loadlibrary ("smartcom411sfj. dll"); // library file provided by the merchant

Pinicom = (inicom) getprocaddress (dllhandle, "inicom"); // find the method name in the library provided by the merchant

Result = pinicom (comport, baudrate );

Freelibrary (dllhandle );

Return result;

}

// Disable the serial port

Jniexport jint jnicall java_smartcard_closecom (jnienv * ENV, jobject Jo, jint comport ){

Closecom pclosecom;

Dllhandle = loadlibrary ("smartcom411sfj. dll ");

Pclosecom = (closecom) getprocaddress (dllhandle, "closecom ");

Result = pclosecom (comport );

Freelibrary (dllhandle );

Return result;

}

 

Jniexport jstring jnicall java_smartcard_readpersonalinfo (jnienv * ENV, jobject Jo, jint comport ){

Idread pidread;

Unsigned char name [8] = "", * Na = Name;

Unsigned char buffer [20] = "put card on it", * Buf = buffer;

Char splitletter [] = "| ";

Jstring jstr;

 

Dllhandle = loadlibrary ("smartcom411sfj. dll ");

Pidread = (idread) getprocaddress (dllhandle, "readpersonalinfo ");

Result = pidread (comport, name, buffer );

Char resultstr [29] = "", * retemp = resultstr;

If (result = 0 ){

For (INT I = 0; I <8; I ++ ){

* (Retemp + I) = * (Na + I );

}

* (Retemp + 8) = splitletter [0];

For (I = 9; I <29; I ++ ){

* (Retemp + I) = * (BUF + I );

}

Jstr = env-> newstringutf (resultstr); // return information in the name and buffer, separated by "|"

} Else if (result =-6 ){

Jstr = env-> newstringutf ("-6 ");

} Else if (result = 1 ){

Jstr = env-> newstringutf ("1 ");

} Else if (result = 16 ){

Jstr = env-> newstringutf ("16 ");

} Else {

Jstr = env-> newstringutf ("-2 ");

}

 

Freelibrary (dllhandle );

Return jstr;

}

4. compile and generate the library file. The generated library file name must be consistent with the Library name in step 1. You can call the corresponding method declared in step 1 in the Java class that needs to use the method in the library provided by the merchant. A test class I wrote is as follows:

Public class test {

Public static void main (string [] ARGs ){

Smartcard SC = new smartcard ();

Int I = SC. inicomtemp (2, 0 );

Int J = SC. closecomtemp (2 );

String STR = SC. readpersonalinfotemp (2 );

System. Out. println (I );

System. Out. println (j );

System. Out. println (STR );

}

}

 

This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/rohsuton/archive/2008/12/29/3637272.aspx#1571539

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.