Skip to content
squid233 edited this page Sep 11, 2022 · 11 revisions

The basic of overrungl is Java FFM API.

Interact with Natives

To interact with native libraries, we don’t use JNI or other JNI-like libraries.

Method Handles

To call a native function, we need to create a downcall handle.

Linker.nativeLinker().downcallHandle(lookup.lookup("nativeFunction"), FunctionDescriptor.of(...));

SymbolLookup::lookup returns an optional of MemorySegment which is nullable. So we can use Optional::orElseThrow to throw an exception when the function is not found.

Also, because the type of argument symbol is an Addressable, we can pass an address of function pointer and get the method handle.

handle = downcallHandle(GLFW.getProcAddress("glGetString") /* it returns a MemoryAddress */, FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.JAVA_INT));

Invoke

MethodHandle::invoke or invokeExact throw a Throwable, so we have to catch it or add to method signature.

Because it is in C, we can simply catch the Throwable and throw an impossible error.

try {
    handle.invoke(...);
} catch (Throwable e) {
    throw new AssertionError("should not reach here");
}

Type Conversion

The general types can easily convert to java value types. This is the type table.

Value Layout Parameter Type C/C++ Type
JAVA_BYTE byte char
JAVA_SHORT short short
JAVA_INT int int
JAVA_LONG long long long
JAVA_CHAR char short
JAVA_BOOLEAN boolean char
JAVA_FLOAT float float
JAVA_DOUBLE double double
ADDRESS Addressable pointer

Any pointer types can directly convert to Addressable even it it a pointer of struct or other pointers of pointer.

✔️ int*
✔️ my_struct*
✔️ void**
✔️ other_struct******

Symbols Naming

OverrunGL removed the macro and function prefix when class name is same as it.

// C: glfwInit()
GLFW.init();
// C: glGetString()
GL10C.getString();
// or
GL.getString();
// C: GL_VERSION, can be used with static import
GLConstC.GL_VERSION
Clone this wiki locally