Skip to content
Olivier Chafik edited this page Nov 8, 2022 · 9 revisions

BridJ's Frequently Asked Questions

What is BridJ ?

BridJ is a library that lets you call C, C++ and Objective-C libraries from Java as if you were writing native code. It is a recent alternative to JNA.

With the help of JNAerator, it provides clean and unambiguous mappings to C/C++ code and a very straightforward and highly typed API to manipulate pointers, classes, structs, unions...

It bridges Java's gap when it comes to native-world interoperability.

For instance, you can allocate a new float[10] almost as in C++ :

void someFunc(float* values);

float* array = new float[10];
float value = array[4];
someFunc(array);
delete[] array;

Scala code :

import org.bridj.Pointer._
...
@native def someFunc(values: Pointer[Float](./Float)): Unit
...
val array = allocateFloats(10)
val value = array(4)
someFunc(values)

// optional : will be eventually called by the Garbage Collector
array.release 

Java code :

import org.bridj.Pointer;
import static org.bridj.Pointer.*;
...
public static native void someFunc(Pointer<Float> values);
...
Pointer<Float> array = allocateFloats(10);
float value = array.get(4);
someFunc(values);
array.release();

Read more about :

Why another interop library ?

In three words : C++, Performance and Usability

What is BridJ's development status ?

Please read CurrentState

What platforms does BridJ support ?

  • Windows (x86, x64)
  • Linux (x86, x64)
  • Mac OS X (x86, x64, ppc)
  • Solaris 10 (x86... soon x64 and sparc)

... with plans for FreeBSD (help and / or test hardward welcome)

BridJ hangs with 100% CPU usage !

If you're on Windows x86 (or on 64 bits windows in a 32 bits JVM), this is typically a case of bad calling convention being used for a native function or callback binding. Please triple-check the calling convention (could it be __stdcall ?) and add a proper @Convention(Convention.Style.xxx) annotation.

How to specify different calling conventions for different platforms ?

Short answer is : you don't need to.

Only Windows x86 has different calling conventions, so @Convention annotations will typically be ignored silently on other platforms.

Can I build BridJ from sources ?

Sure, please read Build.

What is BridJ's license ?

BridJ is dual-licensed under a very liberal BSD license and the very liberal Apache 2.0 license.

How can I help ?

Please read HowToHelp.

What are BridJ's runtime dependencies ?

BridJ is released as a self-contained JAR.

However, it includes a copy of the [ASM] library and its native library are statically linked with a modified version of https://dyncall.org Dyncall.

More details here : CreditsAndLicense.

How do I bind C / C++ function / struct / class / type XXX with BridJ ?

Just paste your C header into JNAerator, choose BridJ as runtime and click on JNAerate.

Where can I get support for BridJ ?

On NativeLibs4Java's mailing-list.

How is BridJ different from...

JNA

Things BridJ aims at doing better than JNA :

  • BridJ is BSD-licensed (while JNA is LGPL)
  • Supports C++ (really : virtual methods, inheritance, templates...)
  • Supports Objective-C, although block support is currently disabled
  • Better structs : lightweight, fast (one or two orders of magnitude faster to create), without any data duplication
  • Better performance in some cases:
    • Direct mode is the default
    • (disabled) Some calls are optimized with assembly code to reach near-JNI performance
  • Supports COM (special case of C++ support) : lets you use "real" Windows APIs (IShellFolder, ITaskBarList3...)
  • Cleaner API with Java 1.5 generics :
import static org.bridj.Pointer.*;
...
Pointer<Integer> p = pointerToInts(1, 2, 3, 4);
p.set(0, 10);
for (int v : p)
  System.out.println("Next value : " + v);
  • Typed enums (that can still be combined as flags)
  • No such thing as IntByReference, LongByReference... Simply use Pointer<Integer>, Pointer<Long>...
  • No such thing as Structure.ByReference vs. Structure.ByValue : if a function accepts a pointer to MyStruct, it's gonna be f(Pointer<MyStruct> s), if it accepts a MyStruct by value it will be f(MyStruct s). Simple.
  • Wanna cast a pointer to a function pointer ? ptr.as(MyFunctionPointer.class).
  • Pervasive multiple endianness support : if you retrieved a pointer to some GPU-filled memory and you know the GPU is little-endian while your CPU is big-endian, you can just call myPtr.order(ByteOrder.LITTLE_ENDIAN). You can then retrieve data from it as usual, and even cast to a struct pointer : it will just work as intended.

Where JNA wins over BridJ :

  • BridJ doesn't handle structs by value in function calls yet (neither in arguments nor in return value). This is being worked on, though.
  • JNA is Java 1.4 compatible (while BridJ requires Java 1.5+)
  • JNA is mature and stable, used by many projects
  • BridJ supports less platforms (Windows 32/64, MacOS X Universal, Linux x86/amd64 for now)
  • BridJ interfaces are harder to write by hand than JNA's. But JNAerator supports both JNA and BridJ outputs (with BridJ output being less verbose because there's only one way to bind things), so you won't need to write any interface by hand anyway.
  • JNA has tons of working examples

SWIG

BridJ's advantages :

  • it only requires you to build your Java program, whereas SWIG requires a painful native build on every target platform
  • the resulting API is generally nicer looking, without any manual configuration involved
  • you work directly with the original C/C++ headers, no need to write special header as with SWIG

SWIG's advantages:

  • it's C++ support is much more solid : once it compiles, you're pretty sure it's gonna work (with BridJ, errors will show up at runtime, typically at startup)
  • it has support for STL types (std::string, std::vector...)
  • it's more mature and stable

Who is using BridJ ?

  • JavaCL has an experimental port to BridJ (over from JNA) which is fully functional.

Please let us know if you want your project to be listed here :-)