Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 78
TypeMapping
If it's a pointer, it's a Pointer !
With BridJ, mapping was kept to its simplest form : if a type is a pointer, it will be mapped to org.bridj.Pointer in Java (or to a subclass of it). This is very different from JNA where there are many possible mappings for the same native type.
C/C++ type | Java/BridJ | JNA |
|---|---|---|
int*, int&, int[] | Pointer<Integer> | IntegerByReference, Pointer, int[], IntBuffer... |
void** | Pointer<Pointer<?>> | PointerByReference, Pointer |
wchar_t | char | char |
struct S* | Pointer<S> | S, S.ByReference, Pointer |
struct S | S | S.ByValue |
enum E | ValuedEnum<E> | int |
const char* | Pointer<Byte> (use getCString() to get the string) | String, Pointer, ByteByReference , ByteBuffer, byte[] |
Note that while NIO buffers are not allowed in bindings (Pointer<Integer> must be used rather than IntBuffer, unlike with JNA), it is trivial to create pointers out of buffers (see Pointer.pointerToBuffer(Buffer), Pointer.pointerToInts(IntBuffer)...) and the other way around (Pointer.getBuffer(), Pointer.getIntBuffer()...).
Please make sure to also read the FAQ
BridJ structs were designed to be performant and easy to use.
Using JNAerator to create them out of C definitions is strongly advised.
C code :
structS {
inta;
void*p;
};
voidfunVal(structSbyVal);
structSmyStruct;
structS*pS=&myStruct;
funVal(myStruct);
funVal(*myStruct);Equivalent Java/BridJ code :
// Generated by JNAerator :publicstaticclassSextendsStructObject {
publicS() { super(); }
publicS(Pointerpointer) { super(pointer); }
@Field(0) publicinta() {
returnthis.io.getIntField(this, 0);
}
// BridJ setters return this to allow invocation chaining@Field(0) publicSa(inta) {
this.io.setIntField(this, 0, a);
returnthis;
}
@Field(1) publicPointer<? > p() {
returnthis.io.getPointerField(this, 1, ?.class);
}
@Field(1) publicSp(Pointer<? > p) {
this.io.setPointerField(this, 1, p);
returnthis;
}
};
SmyStruct = newS(); // maybe chained with setters : new S().a(10).b(12).c(55);Pointer<S> pS = Pointer.getPointer(myStruct);
funVal(myStruct);
funVal(myStruct.get()); // pointer is a reified generic class, so get() returns a correct S instancetypedefenumSimpleEnum {
First=0,
Second=10,
Last=11
} SimpleEnum;Enums don't mean the same in Java and C/C++.
- In Java, an enum item is a singleton subclass of the enum class. It has no associated value besides its index within the list of enum items but is a real class and can implement interfaces and define new fields / methods
- In C/C++, enums are just typed integers (in C++ they're not restricted to int), so you can combine them with bitwise operators
&,|,^,!...
This means that we'd like to benefit from the enum / singleton Java pattern and still be able to pass multiple values to C code expecting enums.
In BridJ, this is made possible with the ValuedEnum<E> interface (and IntValuedEnum<E> subinterface) :
// Generated by JNAerator :publicenumSimpleEnumimplementsIntValuedEnum<SimpleEnum > {
First(0),
Second(10),
Last(11);
SimpleEnum(longvalue) {
this.value = value;
}
publicfinallongvalue;
publiclongvalue() {
returnthis.value;
}
publicIterator<SimpleEnum > iterator() {
returnCollections.singleton(this).iterator();
}
publicstaticValuedEnum<SimpleEnum > fromValue(longvalue) {
returnFlagSet.fromValue(value, values());
}
};
publicstaticnativevoiddoSomething(IntValuedEnum<SimpleEnum> value);
importstaticSimpleEnum.*;
publicvoidtest {
doSomething(First);
// Pass ORed flags : 'First | Value'doSomething(SimpleEnum.fromValue(First.value() | Second.value()));
}C++ code (compiled in test.dll / libtest.dylib / test.so) :
classMyClass {
public:virtual~MyClass();
intsomeMethod();
virtualintsomeVirtualMethod();
};
voidtest() {
MyClass inst;
inst.someMethod();
}BridJ equivalent :
publicclassExample {
// Generated by JNAerator :@Library("test")
publicstaticclassMyClassextendsCPPObject {
publicMyClass() { super(); }
publicMyClass(Pointerpointer) { super(pointer); }
@Virtual(0) publicnativevoidMyClassDestructor();
publicnativeintsomeMethod();
@Virtual(1) publicnativeintsomeVirtualMethod();
};
publicstaticvoidtest() {
MyClassinst = newMyClass();
inst.someMethod();
}
}