使用 JNA 将 Java 类传递到 void* 参数
我在 C 中有一个函数,我试图用 JNA 从 Java
int myCfunc(void *s, int *ls);
调用它 : JNA 文档 void* 需要 com.sun.jna.Pointer
传递给函数。在带有JNA的java中,我相信上述函数将被包装如下:
public interface myWrapper extends Library{
public int myCfunc(Pointer s, IntByReference ls);
}
需要链接到指针并传入参数s
的对象将是实现JNA结构的类,例如:
public class myClass extends Structure{
public int x;
public int y;
public int z;
}
不幸的是,参数ls
是一个整数,表示类的长度(以字节为单位)。 Java 没有 sizeof
函数,因此这增加了额外的复杂性。 我遇到的另一个主要问题是确保我正确地将对象的内容传递到本机内存并返回。
我的代码类似于以下内容:
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.ptr.IntByReference;
public void foo(){
myWrapper wrapper = (myWrapper) Native.loadLibrary("SomeDllWithLegacyCode", myWrapper.class);
myClass myObj = new myClass();
myObj.x = 1;
myObj.y = 2;
Pointer myPointer = myObj.getPointer();
int size = Native.getNativeSize(myClass.class);
IntByReference len = new IntByReference(size);
myObj.write(); //is this required to write the values in myObj into the native memory??
wrapper.myCfunc(myPointer, len);
myObj.read(); //does this read in the native memory and push the values into myObj??
myPointer.clear(size); //is this required to clear the memory and release the Pointer to the GC??
}
我收到一个错误,指出传递的数据的大小比 C 函数预期的要大。
上面的代码大致遵循相同的步骤如本答案中所提供的,针对处理类似问题的问题,但使用的是 C#。我已经尝试并测试了它在 C# 中的工作原理。
我的问题与 Stackoverflow 上的另一个问题类似,但它处理的是指向 IntByReference 的指针,而不是指向类的指针。
I have a function in C which I'm trying to call from Java with JNA:
int myCfunc(void *s, int *ls);
According to the JNA documentation the void* requires a com.sun.jna.Pointer
be passed to the function. In java with JNA I believe the above function will be wrapped as follows:
public interface myWrapper extends Library{
public int myCfunc(Pointer s, IntByReference ls);
}
The objects which need to linked to the Pointer, and passed in parameter s
will be classes which implement JNA Structure, such as:
public class myClass extends Structure{
public int x;
public int y;
public int z;
}
Unfortunately, the parameter ls
is an integer representing the length of the class in bytes. Java doesn't have a sizeof
function, so this adds an extra bit of complexity.
The other major problem I'm having is ensuring I'm correctly passing the contents of the object to native memory and back.
my code is similar to the following:
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.ptr.IntByReference;
public void foo(){
myWrapper wrapper = (myWrapper) Native.loadLibrary("SomeDllWithLegacyCode", myWrapper.class);
myClass myObj = new myClass();
myObj.x = 1;
myObj.y = 2;
Pointer myPointer = myObj.getPointer();
int size = Native.getNativeSize(myClass.class);
IntByReference len = new IntByReference(size);
myObj.write(); //is this required to write the values in myObj into the native memory??
wrapper.myCfunc(myPointer, len);
myObj.read(); //does this read in the native memory and push the values into myObj??
myPointer.clear(size); //is this required to clear the memory and release the Pointer to the GC??
}
I'm getting an error that the data passed is of a larger size than is expected by the C function.
The above code roughly following the same sort of steps as provided out in this answer to a question dealing with a similar issue, but in C#. I've tried and tested that it works in C#.
My question is similar to another on Stackoverflow, but that deals with a Pointer to an IntByReference rather than a pointer to a class.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,JNA 自动处理它自己的内存分配,这意味着下面的行是无用的(并且可能损坏内存堆栈):
接下来它还会自动处理本机指针类型,这意味着下面的两行在您的情况下是等效的:
因此JNA 将为您执行
myObj.write();
和read
操作。以下内容 100% 正确,但我建议您在调用
myCfunc
之前和之后记录len.getValue()
(这将给出 3*4=12 ; 3 int 4 字节):如果所有这些都是正确的,那么您的结构原型可能有错误。
根据我的经验,这主要是由于过时的 C 头文件或过时的库:
最终需要两个 int 和一个字节,您的代码应该如下所示:
您还可以尝试自愿减少 len 的值以进行调试目的
例如:
这不会做你不想做的事情,但至少它应该给你正确的“最大长度”
First of all JNA handle automatically it's own memory allocations which means that to following line is useless (and can damage the memory stack) :
Next it also automatically deal with native pointer types which means that both lines below are equivalent in your case :
and thus JNA will do
myObj.write();
andread
for you.The following is 100% correct but I suggest that you log
len.getValue()
before and after your call tomyCfunc
(which sould give 3*4=12 ; 3 int of 4 bytes) :If all of this is correct then you probably have an error in your structure's prototype.
From my experience this is mostly due to an outdated C header file or an outdated library :
in the end your code should look like this :
You can also try to voluntarily decrease len's value for debugging purposes
eg :
This won't do what you wan't but at least it should give you the correct "max len"