[2014.1.31] Eclipse, MinGW, and JNI compile C ++ to generate the dll. A complete example of a Java-side call is provided.

Source: Internet
Author: User

Problem Background: The previous JNI programming is based on Android NDK tools. The so file is generated for android to call. For details, refer: the current goal of the http://blog.csdn.net/yanzi1225627/article/details/8525720 is to use eclipse CDT MinGW to write C ++ files to generate dynamic link library dll available on the PC for pure Java calls. I thought it was very simple, but I didn't expect it to be done after midnight because many references are too old. Okay, I finally got it for two hours on the first day of the new year. The detailed steps are as follows:

Preparations:

Set jni in the C: \ Program Files \ Java \ jdk1.7.0 _ 45 \ include path. h and C: \ Program Files \ Java \ jdk1.7.0 _ 45 \ include \ win32 copy jni_md.h to the include path under MinGW. Otherwise, the # include <jni. h> and does not recognize the Keyword: jniexport jnicall JNIEnv. Add these two Paths directly to the include column of General --- Paths and Symbols --- gnu c ++ in the C ++ project attributes, for example:


In fact, there is no need to copy the two H files above to the corresponding location!

1. Create a java project named org. yanzi. learnjni. The main class is LearnJNI, that is, the class with the main function. To make the code structure organized, create another package: org. yanzi. mylib and create a class JNILib. java. The Code is as follows:

package org.yanzi.mylib;public class JNILib {static{System.loadLibrary("");}public static native void jniPrint(String str);}

We load the local library in this class. Because the local library is still generated, the parameters in all System. loadLibrary () functions are not currently written. The most important thing is the following sentence: declare the function prototype in jni, input a String, and print it out in jni.

2. Then we use javah in cmd to generate the JNI statement corresponding to the jniPrint () function in JNILib. java. Go to the src folder in the project directory in cmd: E: \ WorkSpaces \ Eclipse_Java \ LearnJNI \ src. Enter the command javah org. yanzi. mylib. JNILib.

Note:: Be sure to enter javah In the src folder. Only the org. yanzi. mylib. JNILib (package name + class name) path after this can be correct.


Refresh the project and you will see the generated. h file:


3. Create a C ++ Project, for example:


Note that the name of this C ++ project is the name of the dll generated in the future libXXX. dll. This is different from ndk. ndk uses the mk file to specify the name of the dynamic link library. Click next and create a new src folder. It is not necessary, just to make the program more regular. Then copy the generated org_yanzi_mylib_JNILib.h to the src folder and create a new cpp file. After that, this. h file will be useful in the java project. It is also possible to delete it. However, to tell the Java caller what the interface is, this h file will be retained. For unification, the cpp file is named org_yanzi_mylib_JNILib.cpp.

The original. h file does not contain parameters. The function body after adding the parameters is:

JNIEXPORT void JNICALL Java_org_yanzi_mylib_JNILib_jniPrint
(JNIEnv * env, jclass jthis, jstring str );

The content of the org_yanzi_mylib_JNILib.h file is as follows:

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class org_yanzi_mylib_JNILib */#ifndef _Included_org_yanzi_mylib_JNILib#define _Included_org_yanzi_mylib_JNILib#ifdef __cplusplusextern "C" {#endif/* * Class:     org_yanzi_mylib_JNILib * Method:    jniPrint * Signature: (Ljava/lang/String;)V */JNIEXPORT void JNICALL Java_org_yanzi_mylib_JNILib_jniPrint  (JNIEnv *env, jclass jthis, jstring str);#ifdef __cplusplus}#endif#endif
The content of the org_yanzi_mylib_JNILib.cpp file is as follows:
/* * org_yanzi_mylib_JNILib.cpp * *  Created on: 2014-2-1 *      Author: Administrator */#include "org_yanzi_mylib_JNILib.h"#include <iostream>using namespace std;JNIEXPORT void JNICALL Java_org_yanzi_mylib_JNILib_jniPrint  (JNIEnv *env, jclass jthis, jstring str){jboolean iscopy = false;const char *charData = env->GetStringUTFChars(str, &iscopy);cout << "Hello, this is from JNI(dll)" <<endl;cout<<"The data from java is:"<<charData << endl;env->ReleaseStringUTFChars(str, charData);}
[ Key Step] Select a project, press alt + enter, and under the Miscellaneous option in the Build ---- Settings ---- Tool Settings ----- MinGW C ++ Linker directory bar, enter-Wl, -- add-stdcall-alias


Then click compile to generate libMyJNILib. dll in the Debug directory. The libXXX. dll name can be found that XXX is the name of our C ++ project.


4. After the dll is generated, the C ++ program will end up. Create a folder libs in the java project. The folder path is in the same level as the src directory. Copy the generated dll to the libs folder.

5 ,[Key Step] Write the parameter libMyJNILib in the System. loadLibrary () function. Note that instead of MyJNILib, it must be the full name. This is different from so generated by ndk-build. The JNILib. java code is as follows:

package org.yanzi.mylib;public class JNILib {static{System.loadLibrary("libMyJNILib");}public static native void jniPrint(String str);}

The LearnJNI. java code is as follows:

package org.yanzi.learnjni;import org.yanzi.mylib.JNILib;public class LearnJNI {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubJNILib.jniPrint("123456");}}

At this moment, the following error occurs when you click run: java. lang. UnsatisfiedLinkError:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no libMyJNILib in java.library.pathat java.lang.ClassLoader.loadLibrary(ClassLoader.java:1886)at java.lang.Runtime.loadLibrary0(Runtime.java:849)at java.lang.System.loadLibrary(System.java:1088)at org.yanzi.mylib.JNILib.<clinit>(JNILib.java:5)at org.yanzi.learnjni.LearnJNI.main(LearnJNI.java:12)
Therefore, the following important steps are required.

6 ,[Key Step] Select a project, click run --- run deployments --- LearnJNI, click Arguments, and fill in the following in the Vm arguments field:-Djava. library. path = "$ {workspace_loc} \ LearnJNI \ libs; $ {env_var: PATH }"

Note: none of the above statements can be wrong. LearnJNI is the name of the java project. Do not enclose the quotation marks at both ends. In addition, the quotation marks are \, because this is in windows.

After these steps, click run, and the long-overdue print will appear:

In addition, in static {
System. loadLibrary ("libMyJNILib ");
}, You can add the following sentence: System. out. println (System. getProperty ("java. library. path "))Print all paths of the path. The overall code is as follows:
package org.yanzi.mylib;public class JNILib {static{System.out.println(System.getProperty("java.library.path"));System.loadLibrary("libMyJNILib");}public static native void jniPrint(String str);}

To sum up, there is a common misunderstanding on the Internet: 1、rename the mingw32-make.exeunder the binfile in mingwas make.exe, which is completely redundant! 2. In the cpp and H files of C ++, add an underscore _. For example, JNIEXPORT void JNICALL _ Java_org_yanzi_mylib_JNILib_jniPrint to the declaration of the function (before the Java keyword ).
(JNIEnv * env, jclass jthis, jstring str) it turns out this step is redundant! 3. In-Djava. library. "" must be included in the path configuration. Some tutorials write :.;. /libs. After printing the path, this is totally nonsense! The configuration in this blog is correct. 4. Some blog posts say that the cpp name in C ++ code must be the same as that in. h. 5. It is also said that the generated H file can be copied to the cpp file as it is. However, it is also possible to retain the H file and include it in the cpp file. We recommend that you do so, which will make the program look more regular.
Reference: http://jingyan.baidu.com/article/9c69d48f53575d13c9024ec1.html
--------------------- This article is original. For more information, see yanzi1225627.
Code download (C ++ and Java): http://download.csdn.net/detail/yanzi1225627/6893971


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.