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

OverrunGL is designed base on Java FFM API.

Interact with Native Libraries

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.find("nativeFunction"), FunctionDescriptor.of(...));

SymbolLookup::find 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 MemorySegment, we can pass an address of function pointer and get the method handle.

handle = downcallHandle(GLFW.getProcAddress("glGetString") /* it returns a MemorySegment */, 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. However, there are still exceptions can be occured, if the function descriptor is not matching the method signature.

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

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 MemorySegment pointer

Any pointer types can directly convert to MemorySegment 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