通过引用在 C 结构内提供 JNA 多个空指针



在我目前的项目中,我必须在java项目中实现本机c库的功能。 我正在使用 JNA。到目前为止,并取得了一些不错的成绩。 现在我陷入了以下问题。

我必须调用本机 c 函数:

int retrieveResult(ResultStruct * pResult)

其中

结构定义如下:
typedef struct tag_ResultStruct
{
const void *pBuffer;
int sizeX;
int sizeY;
} ResultStruct;

在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(){
}
}

我正在调用本机 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);

现在我能够从 sizeX、sizeY 和 pBuffer 中检索预期值

resultStruct.pBuffer.getByteArray(0, bufferLen);

现在我像下面这样扩展我的结构:

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

还有我的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(){
}
}

问题是,我不想使用pContext。所以我不知道它应该有哪个大小,因此我不初始化指针。 现在,当我尝试通过调用从缓冲区中检索值时:

resultStruct.pBuffer.getByteArray(0, bufferLen);

我没有从缓冲区获得预期的值。

问题

使用 JNA 时,如何处理通过引用传递的结构中的多个动态内存字段? 是否可以在结构中保持指针未初始化?

我感谢任何帮助。提前谢谢你。

感谢所有回答我问题的人。你让我走上了正确的轨道。

这是我问题的答案。也许它可以帮助遇到相同或类似问题的其他人。

问题

在我使用的库(Basler的Pylon C API(中,提到您必须注册一个或多个输出缓冲区。它是通过分配缓冲区并注册该数组的指针来完成的。

通常我将一个字节数组(byte[] buffer = new byte[size](映射到一个 uchar* 或 void* 缓冲区。当缓冲区直接填充在 c 函数中时,这有效(就像在 Oo.oO 给我的示例中一样(。

但是在我正在使用的 API 上下文中,指针在寄存器后稍后会填充(当图像数据可用时,它会填充(。 我不是专家,但我认为 java 字节数组不像真正的指针那样工作。

溶液

我将 Java 中的缓冲区分配更改为

Pointer pBuffer = new Memory(size)

并在注册时将此指针映射到 void* 缓冲区指针。 现在缓冲区指针按预期工作,我稍后可以使用

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

当函数retrieveResult(...)返回的指针位于结构内时,这同样有效。

最新更新