7

I'm loading a C DLL from a program written in Java. I want to be able to call one of the methods from the DLL with this declaration :

dll_function(const char* foo1, const char* foo2, const char* foo3, void** bar, size_t* bar2);

How do I call this method with arguments of correct type in Java ? I know (theorically) how to call it, but what I would like to know is how to pass the "void**" and "size_t*" from my Java program ? Basically, I want to know what the "equivalent type" for void and size_t*** is in Java...

I found the Pointer class but didn't manage to get it work ? Many thanks :)

Guillaume Voiron
  • 1,785
  • 2
  • 15
  • 16
  • You don't. The concepts are not mappable. You have to understand how the values will be used and "cheat". Or write a C wrapper. – Hot Licks Apr 15 '13 at 15:29

4 Answers4

2

I worked on a Java/JNI/C project several years ago, and we had to maintain opaque C pointers within Java objects. We used long values on the Java side to hold the C pointers, which were converted on the JNI side from jlong to void* or whatever pointer type we needed.

Since the Java long type is 64 bits wide, and JNI/C pointers are typically either 32 bits or 64 bits wide, we did not have any problems converting between them.

David R Tribble
  • 11,918
  • 5
  • 42
  • 52
1

The size_t is an integer used for the size of a variable in memory; as such you should be safe using unsigned long in Java.

The void* is likely a pointer to an object of unknown type. This question, is quite interesting on the matter. In Java Object is typically used in this case, but I do not know how you would convert between them, though this question might help there.

Community
  • 1
  • 1
Alan
  • 3,307
  • 1
  • 19
  • 22
  • Ah, good point. In that case, `long` in 32-bit code (as it is a 64-bit signed integer), or `BigInteger` in 64-bit code. Thinking on it, so log as you don't actually do anything with it in the Java code you may be able to get away with just a long for 64-bit addressing too, so long as the conversion between Java and the native language doesn't mangle it and can reinterpret the binary as though it were a size_t. – Alan Oct 11 '13 at 12:14
  • 2
    I read the JDK source code. `long` is used for storing "peer objects" in the JDK itself (search for `AWTObject` and look for the `pData` pointer if you are interested). Android source also uses `long` for the same purpose. So I think using `long` is the best practice. – Siu Ching Pong -Asuka Kenji- Oct 15 '13 at 04:54
0

I tried your solutions but I guess I did not really understand correctly... But I solved my problem using this :

import com.sun.jna.ptr.IntByReference;

I called the C function like that in my Java Program :

IntByReference myVoidPointerPointer = new IntByReference();
myCLibrary.myCFunction(myVoidPointerPointer);

The C function "myCFunction" looks like this :

void myCFunction(void** parameter);

Is it OK to do that ? It's working, but I was wondering if it's a correct way to do it.

Guillaume Voiron
  • 1,785
  • 2
  • 15
  • 16
0

It is not the same... a "new" is equivalent to an alloc and return a pointer to a memory zone. So here you just pass the pointer to the memory zone.

What you want is to pass the pointer to the pointer zone. I don't thing the equivalent exists in Java.

Serge
  • 1
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 18 '22 at 06:21