When I make utility software using Processing, I can't get to the itchy place (system environment setting system, etc.)
If you implement it in Swift, you will not have a hard time hitting the API, but
I feel that using Runtime # exec
or ProcessBuilder
on the Java side is something different, so
Somehow I want to hit a function implemented in Swift like a method implemented in Java!
JNA(Java Native Access) Since the substance of Processing is a Java class that inherits the PApplet class, Java grammar and assets can be used
Java has a mechanism called JNI (Java Native Interface) that links with native code implemented in C / C ++. I think that if you use this JNI, you can call the native code implemented in Swift, It is really impossible to write JNI that connects Java and C / C ++ (Create a function with a function name including the package name ...)
Ah, ** I want to call native code from Java ** But ** I don't want to write JNI **
In such a case, use ** JNA (Java Native Access) ** It seems that he will do something good!
For JNA, refer to this area. https://qiita.com/everylittle/items/b888cbec643f14de5ea6
Create the method you want to call from Java, both in the rabbit and in the corner
hello.swift
import Darwin.C
@_cdecl("hello")
public func hello() {
print("Hello")
fflush(stdout)
}
The above program implements a function that displays Hello
on standard output
The point is ** 1. Set the calling convention **, ** 2. Make it public **
It seems that it will not be printed without fflush (stdout)
, so let's put it in
Printf from native code appears only at the end of the java app
https://stackoverrun.com/ja/q/3379588
Let's compile it as it is the source as it is Generate a dynamic link library (lib * .dylib on MacOS) from the above program
Generate dynamic link library
swiftc -emit-library hello.swift
If you execute the above command in the terminal, it will be lib + filename (without extension) + .dylib
A dynamic link library is generated
If you check with the nm command, it seems that the hello
function is in the global section and you can call it something.
Confirm with nm command
cha84rakanal$ nm libhello.dylib
0000000000000e40 T _$S5helloAAyyF
U _$S6Darwin6stdoutSpySo7__sFILEVGvg
U _$SSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
U _$SSSN
U _$Ss27_allocateUninitializedArrayySayxG_BptBwlFyp_Tg5
U _$Ss5print_9separator10terminatoryypd_S2StF
U _$Ss5print_9separator10terminatoryypd_S2StFfA0_
U _$Ss5print_9separator10terminatoryypd_S2StFfA1_
0000000000000fac s ___swift_reflection_version
U __swift_FORCE_LOAD_$_swiftDarwin
0000000000001060 s __swift_FORCE_LOAD_$_swiftDarwin_$_hello
U _fflush
0000000000000e30 T _hello
U _swift_bridgeObjectRelease
U _swift_bridgeObjectRetain
U dyld_stub_binder
cha84rakanal$
Now, let's actually call the Hello function
created earlier from the Processing (Java) side.
Put the dynamically generated dynamic link library in the data directory of the sketch and move it with the next sketch!
JNAProcessing.pde
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
public interface SwiftLib extends Library {
void hello();
}
SwiftLib mylib;
void setup(){
mylib = (SwiftLib) Native.loadLibrary(dataPath("libhello.dylib"), SwiftLib.class);
mylib.hello();
}
void draw(){
}
The point is
Native # loadLibrary
, and if you only use the library name, go to the path of the dynamic library referenced by Java, and be sure to enter it with an absolute path.If Hello is displayed, it's OK! All you have to do is implement whatever you like in Swift! Well then, good Processing Life
Recommended Posts