[英]JNA - VM crashes when try to access to a C function with void* param
我有以下代码:
public class TTM {
public interface WrapperDLL extends Library {
WrapperDLL INSTANCE = (WrapperDLL) Native.loadLibrary("TransportRE", WrapperDLL.class);
int TRE_send(int channel, Pointer data, int len);
}
public int Send (int channel, String data, int len) {
WrapperDLL wdll = WrapperDLL.INSTANCE;
Memory mem = new Memory(data.length()+1);
mem.setString(0, data);
int byteSent = wdll.TRE_send(channel_id, mem.getPointer(0), len);
// at this (TRE_send) point the VM crashes !!!!
return byteSent;
}
}
看看我尝试过的JNA API:
public int Send (int channel, String data, int len) {
WrapperDLL wdll = WrapperDLL.INSTANCE;
Memory mem = new Memory(data.length()+1);
mem.setString(0, data);
int byteSent = wdll.TRE_send(channel_id, mem, len);
return byteSent;
}
这次不会崩溃,但无法正常工作(byteSent = 0!)
一些提示?
您正在取消对String
引用,就好像它包含指针而不是字符数据一样。
Pointer.getPointer(0)
尝试从给定的指针地址中提取指针值; 您一定要像第二个片段一样直接传递指针值。
JNA允许您直接传递String
值,将其自动转换为C字符串(NUL终止的字节数组)。 但是,尚不清楚您的本机方法是否需要字符串。 它可能需要特殊格式的字节缓冲区。
如果len
是要发送的缓冲区的长度,则它应该是字符串的长度加1(或要传递的Memory
的大小)。
编辑
您暗示DLL总是强制转换为char *
,在这种情况下,您只需按原样传递String
即可。 如果您的DLL有时需要非ASCII数据,则应传递Memory
并使用其成员函数写入所需的数据。 请注意,您可以使用不同的签名定义DLL的多个版本,例如
void send(String);
void send(Pointer);
void send(MyStructure);
我已经解决了!
int byteSent = wdll.TRE_send(channel_id, data.toCharArray(), len);
由于第二个参数是void *,但是在dll代码中,第一件事是将其强制转换为char *。我使用了相同的类型,现在它可以工作了。
确保这不是“通用解决方案”,因为“ TRE_send”想要一个void *类型...您如何看待?
再见
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.