在 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 文档,似乎 Pointer
或 PointerByReference
都适用于这个简化示例。
JNA中指针的三种一般表示:
Pointer
class,它有几种从 pointed-to 本机内存读取和写入的方法。
-
PointerType
class 可以扩展为表示没有其他功能的指针,如果不需要 Pointer
功能则更好。
<something>ByReference
classes 的集合,它们是指向特定类型对象的指针。
因为你所做的只是操纵指针值,所以这些都可以工作:更重要的一点是你传递了一个与你从 [=17 中检索到的 class 相同的指针对象=] 这是一个指针(指向你从未处理过的东西)。
注意:这部分代码可能没有按照您的预期执行:
Clp_deleteModel(a.getPointer());
getPointer()
方法 returns class 的指针,而不是指向的值。 a
和 a.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 .
在 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 文档,似乎 Pointer
或 PointerByReference
都适用于这个简化示例。
JNA中指针的三种一般表示:
Pointer
class,它有几种从 pointed-to 本机内存读取和写入的方法。-
PointerType
class 可以扩展为表示没有其他功能的指针,如果不需要Pointer
功能则更好。 <something>ByReference
classes 的集合,它们是指向特定类型对象的指针。
因为你所做的只是操纵指针值,所以这些都可以工作:更重要的一点是你传递了一个与你从 [=17 中检索到的 class 相同的指针对象=] 这是一个指针(指向你从未处理过的东西)。
注意:这部分代码可能没有按照您的预期执行:
Clp_deleteModel(a.getPointer());
getPointer()
方法 returns class 的指针,而不是指向的值。 a
和 a.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 .