Java 如何使用jna将字节[]映射到void*缓冲区?

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

我有以下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 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代码的权限…但是它被支持进行测试等等,所以我假设它没问题,问题就在我这边。。。