在 JNA 中为 C 中的指针参数传递指针或 PointerByReference

Pass pointer or PointerByReference in JNA for pointer argument in C

在 C++ 中,我有以下头文件:

/** Default constructor */
CLPLIB_EXPORT Clp_Simplex *CLP_LINKAGE Clp_newModel(void);

/** Destructor */
CLPLIB_EXPORT void CLP_LINKAGE Clp_deleteModel(Clp_Simplex *model);

试图用 JNA 导入它,我假设我必须这样指定它们:

public static native PointerByReference Clp_newModel();

public static native void Clp_deleteModel(Pointer pModel);

这是正确的,还是应该 Clp_deleteModel(PointerByReference pModel)?奇怪的是,两者似乎都适用于一个非常简单的测试,尽管前者对我来说确实更有意义。我认为 JNA 发挥了它的一些魔力。

// option 1
PointerByReference a = Clp_newModel();
ChangeSomthingIntheModel(a,2);
Clp_deleteModel(a.getPointer());
ChangeSomthingIntheModel(a,2); // the JVM signals "illegal memory access here

// option 2
PointerByReference a = Clp_newModel();
ChangeSomthingIntheModel(a,2);
Clp_deleteModel(a); // passing the PointerByReference here! 
ChangeSomthingIntheModel(a,2); // the JVM signals "illegal memory access here

查看 CLP 文档,似乎 PointerPointerByReference 都适用于这个简化示例。

JNA中指针的三种一般表示:

  • Pointer class,它有几种从 pointed-to 本机内存读取和写入的方法。
  • PointerType class 可以扩展为表示没有其他功能的指针,如果不需要 Pointer 功能则更好。
  • <something>ByReference classes 的集合,它们是指向特定类型对象的指针。

因为你所做的只是操纵指针值,所以这些都可以工作:更重要的一点是你传递了一个与你从 [=17 中检索到的 class 相同的指针对象=] 这是一个指针(指向你从未处理过的东西)。

注意:这部分代码可能没有按照您的预期执行:

Clp_deleteModel(a.getPointer());

getPointer() 方法 returns class 的指针,而不是指向的值。 aa.getPointer() 在您的用法上没有根本区别(class 类型除外)。 (您可能打算使用 a.getValue() 和 returns 的 pointed-to 值,这会有所不同,并且可能 而不是 您想要的。)

当前您检索到一个 PointerByReference,因此您可以(通过 .getValue())访问所指向的内容,这似乎是一个 CLP_LINKAGE,但似乎不是您将永远操纵的对象。所以你可以在那里检索一个普通的 Pointer (不知道它指向什么)。然后您会将相同的指针传递给 Clp-deleteModel(a).

如果您永远不会访问 pointed-to 值,您可以简单地使用 Pointer,但是,限制 API、类型安全和 self-documenting 代码定义 class 扩展 PointerType。在您的情况下,CLPSimplexPtr extends PointerType 将是一个不错的选择。

如果需要了解返回的指针指向的指针值(CLP_LINKAGE),则使用适当的 <whatever>ByReference 扩展 ByReference 并实现setValue()getValue() 方法。

您可能感兴趣的是,似乎有一个 clp-java project 使用 BridJ 实现 CLP,另一个 Java-to-native 库(它使用 JNA 但有很多针对 C++ 的优化)。对于两个映射,它们的定义都是 Pointer<CLPSimplex>,如果你用 JNA 编写它,它将与 CLPSimplexPtr class 对齐——它仍然是一个修饰的普通指针,但是一个 type-safe .