2013-10-29 60 views
1

我有以下的C函数:如何将jna的一个字节[]映射到void *缓冲区?

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; 

而且我有将其转换为java,以jna与以下内容:

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_read(int playdev,指针缓冲区,int count);

ByteBuffer bf = ByteBuffer.wrap(data.buffer); 
    Pointer pbuf = Native.getDirectBufferPointer(bf); 
    clib.read(data.dev, pbuf, READ_SIZE); 

,它给了我同样的结果。

请问,任何想法,使其工作?

+0

您可以直接传递'byte []',使用NIO缓冲区或使用JNA'Memory'。 JNA支持所有三个作为缓冲区类型参数。 – technomage

+0

请用您的*实际*代码更新您的问题。你不指出你如何初始化'buf'或'data.buffer';那很可能是你错误所在的地方。 – technomage

+0

我编辑了答案。使用“buf”,我的意思是“bf”,它是相同的,我创建缓冲区,并用它构建de指针。我已经直接尝试了byte [],但没有使用Memory,我不知道你怎么说可以在这里应用。 – Selvaya

回答

1

尝试创建与ByteBuffer.allocateDirect ByteBuffer,然后使用byteBuffer.put(..)如果你想设置任何初始数据。此外,重置缓冲区的位置,buffer.position(0)。

ByteBuffer bb = ByteBuffer.allocateDirect(values.length); 
bb.put(values); 
bb.position(0); 

阅读Edwin的回复here为了使用allocateDirect。

+0

我试过用ByteBuffer buf = ByteBuffer.allocateDirect(32000); \t \t \t buf.put(data.buffer);和结果是​​相同的“java.lang.Error:无效的内存访问” – Selvaya

+0

..你重置位置为0,与buf.position(0)和data.buffer.length == 32000?你可以用一个简单的函数来测试它,它会得到这样一个指针,然后尝试在那里放置几个字节,在本地函数返回之后,你可以在java端检查它。 – radical

+0

随着你的修改,结果和以前一样: – Selvaya

1

technomage对原帖的评论完全正确。明确地说,在Java端,声明你JNA接口方法,你打算使用它:

int read(int playdev, byte[] buffer, int count); 

clib.read(data.dev, data.buffer, READ_SIZE); 

无需使用缓冲区或字节缓冲区。另外,根据读取函数是否导出__cdecl或__stdcall,您的JNA接口应分别为extends Libraryextends StdCallLibrary