简体   繁体   English

JNA 通过引用在 C 结构中使用多个空指针

[英]JNA multiple void pointers inside a C struct by reference

In my current project I have to implement the function of native c libs in a java project.在我目前的项目中,我必须在一个java项目中实现原生c库的功能。 I'm using JNA.我正在使用 JNA。 And reached some good results so far.并且到目前为止取得了一些不错的结果。 Now I'm stuck on the following problem.现在我被困在以下问题上。

I have to call the native c function:我必须调用本机 c 函数:

int retrieveResult(ResultStruct * pResult)

Where the Struct is defined like followed:结构定义如下:

typedef struct tag_ResultStruct
{
const void *pBuffer;
int sizeX;
int sizeY;
} ResultStruct;

In Java I created a class representing the struct:在 Java 中,我创建了一个表示结构的类:

public class ResultStruct extends Structure{
   public Pointer pBuffer;
   public int sizeX;
   public int sizeY;

   @Override
   protected List<String> getFieldOrder(){
      return Arrays.asList(new String[] {"pBuffer", "sizeX", "sizeY"});
   }

   public ResultStruct(){

   }
}

I'm calling the Native C Method with我正在调用本机 C 方法

private interface MyCLib extends Library{
   MyCLib INSTANCE = Native.load("myclib", MyCLib.class);
   int retrieveResult(ResultStruct pResult);
}
ResultStruct resultStruct = new ResultStruct();
resultStruct.pBuffer = new Memory(bufferLen);
int res = MyCLib.INSTANCE.retrieveResult(resultStruct);

Now I'm able to retrieve the expected values from sizeX, sizeY and pBuffer with现在我可以从 sizeX、sizeY 和 pBuffer 中检索预期值

resultStruct.pBuffer.getByteArray(0, bufferLen);

Now I' extending my struct like the following:现在我像下面这样扩展我的结构:

typedef struct tag_ResultStruct
{
const void* pContext;
const void *pBuffer;
int sizeX;
int sizeY;
} ResultStruct;

And my Java Structure:还有我的 Java 结构:

public class ResultStruct extends Structure{
   public Pointer pContext;
   public Pointer pBuffer;
   public int sizeX;
   public int sizeY;

   @Override
   protected List<String> getFieldOrder(){
      return Arrays.asList(new String[] {"pContext", "pBuffer", "sizeX", "sizeY"});
   }

   public ResultStruct(){

   }
}

Problem is, i don't want to make use of pContext.问题是,我不想使用 pContext。 So I don't know which size it should have and therefore i don't initialize the pointer.所以我不知道它应该有多大,因此我不初始化指针。 Now when i try to retrieve the values from the buffer by calling:现在,当我尝试通过调用从缓冲区中检索值时:

resultStruct.pBuffer.getByteArray(0, bufferLen);

I don't get the expected values from buffer.我没有从缓冲区获得预期值。

Question

How to deal with more than dynamic memory field inside a Structure passed by reference when using JNA?使用 JNA 时如何处理通过引用传递的结构中的多个动态内存字段? It is possible to leave Pointer uninitialized inside the Structure?是否可以在结构内保留未初始化的指针?

I Appreciate any help.我很感激任何帮助。 Thank you in advance.先感谢您。

Thanks to all, who replied to my question.谢谢大家,谁回答了我的问题。 You set me on the right track.你让我走上了正轨。

Answer回答

Here is the answer to my question.这是我的问题的答案。 Maybe it may help someone other encountering the same or a similar problem.也许它可以帮助其他遇到相同或类似问题的人。

Problem问题

In the library which I use (Pylon C API from Basler) it is mentioned that you have to register one or more output buffers.在我使用的库(Basler 的 Pylon C API)中提到您必须注册一个或多个输出缓冲区。 It is done by allocating the buffer and register the pointer of that array.它是通过分配缓冲区并注册该数组的指针来完成的。

Usually I map a byte array ( byte[] buffer = new byte[size] ) to a uchar* or void* buffer.通常我将一个字节数组( byte[] buffer = new byte[size] )映射到一个 uchar* 或 void* 缓冲区。 This works, when the buffer is filled directly in you c function (like in the sample that Oo.oO gave me).这是有效的,当缓冲区直接填充到你的 c 函数中时(就像在 Oo.oO 给我的示例中)。

But in the context of the API that I'm using, the pointer gets filled a bit later after it was registeres (it gets filled, when image data is available).但是在我使用的 API 的上下文中,指针在注册后稍后会被填充(它被填充,当图像数据可用时)。 I'm not an expert, but I think the java byte array, doesn't work like a real pointer.我不是专家,但我认为 java 字节数组不像真正的指针那样工作。

Solution解决方案

I changed the buffer allocation in Java to我将 Java 中的缓冲区分配更改为

Pointer pBuffer = new Memory(size)

and mapped this Pointer to the void* buffer pointer, when registering it.并在注册时将此指针映射到 void* 缓冲区指针。 Now the buffer Pointer works as expected and I can retrieve the content of the buffer later by using现在缓冲区指针按预期工作,我可以稍后通过使用检索缓冲区的内容

byte[] data = pBuffer.getByteArray(0, size)

This also works, when the pointer returned by the function retrieveResult(...) is inside a struct.当函数retrieveResult(...)返回的指针在结构内时,这也有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM