Java 如何使用jna将字节[]映射到void*缓冲区?
我有以下C函数:Java 如何使用jna将字节[]映射到void*缓冲区?,java,c,jna,Java,C,Jna,我有以下C函数: int read(int dev, void* buffer, unsigned int count) 这通常是C中的调用,如: read(data->dev, data->buffer, 32000); 数据是一个结构,具有以下特性: typedef struct { ssize_t dev; char buffer[32000]; } DATA; public class Da
int read(int dev, void* buffer, unsigned int count)
这通常是C中的调用,如:
read(data->dev, data->buffer, 32000);
数据是一个结构,具有以下特性:
typedef struct {
ssize_t dev;
char buffer[32000];
} DATA;
public class Data{//not neccesary to extends of Structure, because is only used to package both variables together
public int dev;
public byte[] buffer;//in the constructor of the class set to 32000 elements
}
int read(int playdev, Buffer buffer, int count);
//clib is the class to connect with de C library
ByteBuffer bf = ByteBuffer.wrap(data.buffer);
clib.read(data.dev, bf , READ_SIZE);
我已经将其转换为java,jna具有以下功能:
typedef struct {
ssize_t dev;
char buffer[32000];
} DATA;
public class Data{//not neccesary to extends of Structure, because is only used to package both variables together
public int dev;
public byte[] buffer;//in the constructor of the class set to 32000 elements
}
int read(int playdev, Buffer buffer, int count);
//clib is the class to connect with de C library
ByteBuffer bf = ByteBuffer.wrap(data.buffer);
clib.read(data.dev, bf , READ_SIZE);
当我执行“clib.read”时,它会给我一个“java.lang.Error:无效内存访问”
你知道如何克服这个错误吗
我试着做一个:
int vox_playstr_读取(int playdev、指针缓冲区、int计数)
与
它给了我同样的结果
请问,有什么办法可以让它工作吗?如果要设置任何初始数据,请尝试使用创建ByteBuffer,然后使用ByteBuffer.put(..)。另外,重置缓冲器的位置,buffer.position(0)
阅读Edwin的回复,了解使用allocateDirect的原因。technomage对原始帖子的评论完全正确。明确地说,在Java方面,在计划使用JNA接口方法时声明它:
int read(int playdev, byte[] buffer, int count);
clib.read(data.dev, data.buffer, READ_SIZE);
无需使用缓冲区或ByteBuffer。另外,根据read函数是导出的cdecl还是stdcall,JNA接口应该分别
扩展库
或扩展stdcall库
。我用ByteBuffer buf=ByteBuffer.allocateDirect(32000)进行了尝试;buf.put(数据缓冲区);结果是相同的“java.lang.Error:无效内存访问”。。然后将位置重置为0,buf.position(0)和data.buffer.length==32000?您可以使用一个简单的函数进行测试,该函数获取这样一个指针,并尝试在那里放入几个字节,在本机函数返回后,您可以在java端检查这些字节。经过修改后,结果与之前相同:(我今天在研究这个问题时发现了这个问题。你必须记住JVM和底层机器之间的endiannes差异。我会在分配后立即使用ByteBuffer.order(ByteOrder.nativeOrder())
。你可以传递byte[]
直接使用NIO缓冲区,或使用JNA内存
。JNA支持所有三个作为缓冲区类型的参数。请使用实际代码更新您的问题。您没有说明如何初始化buf
或数据。buffer
;这很可能是您的错误所在。我已经用“buf”编辑了答案,我的意思是“bf”,这是一样的,我创建缓冲区并用它构建反指针。我已经直接用byte[]尝试过了,但没有用内存,我不知道你怎么说它可以在这里应用。Native.getDirectBufferAddress()
不适用于包装基元数组的NIO缓冲区。使用bf=ByteBuffer.allocateDirect(大小)
相反。无论如何,您应该能够将字节缓冲
直接传递到读取
功能;您还应该能够传递字节[]
直接到读取
。将调试添加到C函数中,以吐出它接收到的参数;如果参数不正确,则很可能是调用约定或签名错误。在下面的Radical答案中,我说我尝试了bf=ByteBuffer.allocateDirect(大小)我不能调试de C函数,因为它在一个*.dll中,我没有访问真正的C代码的权限…但是它被支持进行测试等等,所以我假设它没问题,问题就在我这边。。。