Step 4: Java Main Function
Run Java without the CToCPPHelper Entry Point
- Create the following Java Class:
package com.mycompany.myapp;
public class JavaToCHelper {
public native void cToCPPHelperEntryPoint(); // Comment to ignore CToCPPHelper
static // static initializer code
{
// System.load(JavaToCHelper.class.getResource("/dlls/CToCPPHelper.dll").getPath()); // Comment to ignore CToCPPHelper
}
public void jToCHelperExitPoint() {
System.out.println("JAVA_TO_C_HELPER EXIT START");
// cToCPPHelperEntryPoint(); // Comment to ignore CToCPPHelper
System.out.println("JAVA_TO_C_HELPER EXIT FINISH");
}
public static void main(String[] args) {
System.out.println("JAVA_TO_C_HELPER MAIN START");
JavaToCHelper jToCHelper = new JavaToCHelper();
jToCHelper.jToCHelperExitPoint();
System.out.println("JAVA_TO_C_HELPER MAIN FINISH");
}
public void jToCHelperEntryPoint() {
System.out.println("JAVA_TO_C_HELPER ENTRY START");
jToCHelperExitPoint();
System.out.println("JAVA_TO_C_HELPER ENTRY FINISH");
}
} - Compile and run JavaToCHelper, using the following commands:
cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\java"
"C:\Program Files\Java\jdk1.6.0_26\bin\javac.exe" -classpath "." com\mycompany\myapp\JavaToCHelper.java
"C:\Program Files\Java\jdk1.6.0_26\bin\java.exe" -classpath "." com.mycompany.myapp.JavaToCHelper
Run CToCPPHelper.exe with a Generated Header File
- Generate CToCPPHelper.h from JavaToCHelper.class, using the following commands:
cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\java"
"C:\Program Files\Java\jdk1.6.0_26\bin\javah.exe" -classpath "." com.mycompany.myapp.JavaToCHelper
mv com_mycompany_myapp_JavaToCHelper.h "C:\Users\Scott\workspace\myrepo\my-app\src\main\resources\dlls\CToCPPHelper.h"
- Verify the CToCPPHelper.h was generated in the same folder as CToCPPHelper.c:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_mycompany_myapp_JavaToCHelper */
#ifndef _Included_com_mycompany_myapp_JavaToCHelper
#define _Included_com_mycompany_myapp_JavaToCHelper
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_mycompany_myapp_JavaToCHelper
* Method: cToCPPHelperEntryPoint
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_mycompany_myapp_JavaToCHelper_cToCPPHelperEntryPoint
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif - Compile the code and run "CToCPPHelper.exe" (see An Introduction to JNI using a Bottom Up Approach: Step 3).
Run JavaToCHelper with the New DLL
- Uncomment two lines of code:
System.load(JavaToCHelper.class.getResource("/dlls/CToCPPHelper.dll").getPath()); // Comment to ignore CToCPPHelper
cToCPPHelperEntryPoint(); // Comment to ignore CToCPPHelper - Generate a 64 bit dll file (for 32 bit Java, remove "-m64") using the following commands:
cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\resources\dlls"
"C:\MinGW64\bin\g++.exe" -m64 -Wl,--add-stdcall-alias -shared -I"C:\Program Files\Java\jdk1.6.0_26\include" -I"C:\Program Files\Java\jdk1.6.0_26\include\win32" -o CToCPPHelper.dll CToCPPHelper.c CPPHelper.cpp PrintOpenWindows.cpp
- Compile and run JavaToCHelper (adding the new dll to the class path), using the following commands:
cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\java"
"C:\Program Files\Java\jdk1.6.0_26\bin\javac.exe" -classpath "." com\mycompany\myapp\JavaToCHelper.java
"C:\Program Files\Java\jdk1.6.0_26\bin\java.exe" -classpath ".;../resources" com.mycompany.myapp.JavaToCHelper
Summary of commands
Anytime you change the JavaToCHelper.java, CToCPPHelper.c, CPPHelper.cpp or PrintOpenWindows.cpp, you can regenerate the appropriate files via:
REM Generate the New C Header File
cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\java"
"C:\Program Files\Java\jdk1.6.0_26\bin\javac.exe" -classpath "." com\mycompany\myapp\JavaToCHelper.java
"C:\Program Files\Java\jdk1.6.0_26\bin\javah.exe" -classpath "." com.mycompany.myapp.JavaToCHelper
mv com_mycompany_myapp_JavaToCHelper.h "C:\Users\Scott\workspace\myrepo\my-app\src\main\resources\dlls\CToCPPHelper.h"
REM Generate the New DLL
cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\resources\dlls"
"C:\MinGW64\bin\g++.exe" -m64 -Wl,--add-stdcall-alias -shared -I"C:\Program Files\Java\jdk1.6.0_26\include" -I"C:\Program Files\Java\jdk1.6.0_26\include\win32" -o CToCPPHelper.dll CToCPPHelper.c CPPHelper.cpp PrintOpenWindows.cpp
REM Run Java
cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\java"
"C:\Program Files\Java\jdk1.6.0_26\bin\java.exe" -classpath ".;../resources" com.mycompany.myapp.JavaToCHelper
cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\java"
"C:\Program Files\Java\jdk1.6.0_26\bin\javac.exe" -classpath "." com\mycompany\myapp\JavaToCHelper.java
"C:\Program Files\Java\jdk1.6.0_26\bin\javah.exe" -classpath "." com.mycompany.myapp.JavaToCHelper
mv com_mycompany_myapp_JavaToCHelper.h "C:\Users\Scott\workspace\myrepo\my-app\src\main\resources\dlls\CToCPPHelper.h"
REM Generate the New DLL
cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\resources\dlls"
"C:\MinGW64\bin\g++.exe" -m64 -Wl,--add-stdcall-alias -shared -I"C:\Program Files\Java\jdk1.6.0_26\include" -I"C:\Program Files\Java\jdk1.6.0_26\include\win32" -o CToCPPHelper.dll CToCPPHelper.c CPPHelper.cpp PrintOpenWindows.cpp
REM Run Java
cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\java"
"C:\Program Files\Java\jdk1.6.0_26\bin\java.exe" -classpath ".;../resources" com.mycompany.myapp.JavaToCHelper
A warning! If you followed these instructions and you received the error "Can't load this .dll (machine code=0xbd) on a AMD 64-bit platform", it may be because your project is a "Maven Project". You can "Disable Maven Nature" and try recompiling from the command line with the following command:
mvn eclipse:clean eclipse:eclipse clean compile test-compile
Also, you can run the JavaToCHelper by right clicking and "Run As Java Application" or executing this command.
mvn exec:java -Dexec.mainClass="com.mycompany.myapp.JavaToCHelper"
This assumes your src/main/resources folder will be copied to the target folder during the build phase.
<build>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
</plugin>
</plugins>
</build>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
</plugin>
</plugins>
</build>
This post was reposted from http://scottizu.wordpress.com/2013/08/21/an-introduction-to-jni-using-a-bottom-up-approach-step-4/, originally written on August 21st, 2013.
You will have to change "jdk1.6.0_26" to your current jdk in all the commands and will have to change "com" "mycompany" "myapp" to match the current package of JavaToCHelper.
ReplyDeleteThe 'mv' command is 'move' since this is a Windows command prompt.
The String in the getResource needs to be relative to the class. So if you have JavaToCHelper.java in src/main/java folder and com.mycompany.app.dlls package and if you have CToCPPHelper.dll is in src/main/resources folder and com.mycompany.app.dlls package, you would use getResource("CToCPPHelper.dll").
Thanks for sharing this article the above article having a good content and valuable information.
ReplyDelete