visit
Disclaimers:
I’ll use Windows and more particularly Visual C++ with its Inline Assembler. If you use MacOs or Linux you will have significant differences comparing to what is described in the article.
Everything below is shown mostly for demonstration purposes
Java is mature self-sufficient language, though as we all know it is possible to “connect” java to C (via Java-Native-Interface or JNI) to speed up some critical pieces of code.
Also for C/C++ it is possible to delegate some even more critical pieces of code directly to Assembly.
Setup
First of all we need to download .
I have pretty old version installed, but feel free to install newer version.
After installation verify that everything works:
>java -version
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) Client VM (build 25.121-b13, mixed mode, sharing)
Code
Here is our program: main function, parsing command line arguments and our target method “sum” (with implementation in java):public class Test {
public static void main(String[] args) {
if (args.length != 2) {
System.out.println("Error: wrong params count");
return;
}
int a;
try {
a = Integer.parseInt(args[0]);
} catch (Throwable throwable) {
System.out.println("First param is not a number");
return;
}
int b;
try {
b = Integer.parseInt(args[1]);
} catch (Throwable throwable) {
System.out.println("Second param is not a number");
return;
}
Test test = new Test();
System.out.println(test.sum(a, b));
}
public static int sum(int a, int b) {
return a + b;
}
}
Compile
In order to run the program we first need to compile it with java compiler. It will generate
Test.class
binary file which we’ll later on execute.> javac Test.java
Execute
To execute program call java and provide arguments. See that our program works correctly and prints sum of numbers.> java Test 3 4
7
Setup
Install and using it install Visual C++ build tools:choco install visualcpp-build-tools
We’ll need these tools to compile C files into library dll file. Specifically for compilation we’ll need
cl
command, so check that it works:>cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27031.1 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
public class Test {
public static void main(String[] args) {
if (args.length != 2) {
System.out.println("Error: wrong params count");
return;
}
int a;
try {
a = Integer.parseInt(args[0]);
} catch (Throwable throwable) {
System.out.println("First param is not a number");
return;
}
int b;
try {
b = Integer.parseInt(args[1]);
} catch (Throwable throwable) {
System.out.println("Second param is not a number");
return;
}
System.loadLibrary("Test");
Test test = new Test();
System.out.println(test.sum(a, b));
}
public native int sum(int a, int b);
}
First, instead of static method with implementation we provide so called native method. It doesn’t have any implementation because we expect it to be provided via JNI. Second, we need to load our C library — and we do that with
System.loadLibrary
method.After we updated our program we need to generate Test.h header file:> javah Test
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Test */
#ifndef _Included_Test
#define _Included_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Test
* Method: sum
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_Test_sum
(JNIEnv *, jobject, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
#include "Test.h"
JNIEXPORT jint JNICALL Java_Test_sum
(JNIEnv *env, jobject obj, jint a, jint b) {
return a + b;
}
void main() {}
> cl -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" -LD Test.c -FeTest.dll
> java Test 3 4
7
Previously we had C implementation which looked basically as on java:
a + b
. When we work with Assembly we work on a lower level so such small operations require quite more code. __asm block
— which is Inline Assembler for Visual C++.eax
, put our variable b
into register ebx
. Then we make a sum from contents of registers and store it in the eax
register (this is what add command does).eax
register in our result field:#include "Test.h"
#include <stdio.h>
JNIEXPORT jint JNICALL Java_Test_sum
(JNIEnv *env, jobject obj, jint a, jint b) {
int result;
__asm {
mov eax, a
mov ebx, b
add eax, ebx
mov result, eax
}
return result;
}
void main() {}
> java Test 3 4
7
References