简体   繁体   English

通过引用传递结构作为 JNA 中的参数

[英]Pass Structure by reference as argument in JNA

I have a dynamic link library (DLL) written in c++.我有一个用 C++ 编写的动态链接库 (DLL)。 In my DLL I have a function like this:在我的 DLL 中,我有一个这样的函数:

void anpr_set_params(byte instance, SLPRParams* params);

Where SLPRParams is a Structure containing byte, int, float and array of them.其中SLPRParams是一个包含 byte、int、float 和它们的数组的结构。

Now, I want to use my DLL in Java.现在,我想在 Java 中使用我的 DLL。 I'm using JNA to call native code in my java project.我正在使用 JNA 在我的 java 项目中调用本机代码。 I tried get help from this site to get the address of my structure in java and pass it to my dll, and I defined my signature function in Java like this:我尝试从该站点获取帮助以获取我在 java 中的结构的地址并将其传递给我的 dll,我在 Java 中定义了我的签名函数,如下所示:

void anpr_set_params(byte instance, long slpr_params);

But the address i get in c++ is different from the address i sent in Java.但是我在 c++ 中获得的地址与我在 Java 中发送的地址不同。

Then I looked for another solution and read the this JNA FAQ entry .然后我寻找另一个解决方案并阅读了这个JNA FAQ entry

I tested all types but every time I get a runtime error.我测试了所有类型,但每次遇到运行时错误。

You can just pass the Structure directly as an argument.您可以直接将Structure作为参数传递。

As explained in JNA Structures and Unions ,JNA 结构和联合中所述,

When a function requires a pointer to a struct, a Java Structure should be used.当函数需要指向结构的指针时,应使用 Java 结构。

Also, the javadoc for Structure says:此外, Structure的 javadoc说:

When used as a function parameter or return value, this class corresponds to struct* .当用作函数参数或返回值时,此类对应于struct* When used as a field within another Structure , it corresponds to struct .当用作另一个Structure中的字段时,它对应于struct The tagging interfaces Structure.ByReference and Structure.ByValue may be used to alter the default behavior.标记接口Structure.ByReferenceStructure.ByValue可用于更改默认行为。

Passing a pointer to a structure like SLPRParams* params is the most common way that DLLs expect structures, and that ByReference type is the default behavior.传递指向SLPRParams* params之类的结构的指针是 DLL 期望结构的最常见方式,并且ByReference类型是默认行为。 Only if the full structure is passed inline would you need to use the ByValue tag on it.只有当完整的结构被内联传递时,您才需要在其上使用ByValue标记。

A nested Structure inside another Structure works the opposite way;另一个结构中的嵌套结构以相反的方式工作; it is ByValue by default and would need the ByReference tag if it was declared as a pointer.默认情况下它是ByValue ,如果它被声明为指针,则需要ByReference标记。

The examples in the JNA FAQ (which you also linked) may make more sense once you understand this distinction.一旦您了解了这种区别,JNA 常见问题解答(您也已链接)中的示例可能会更有意义。 The relevant example is this one:相关的例子是这个:

void myfunc(simplestruct* data); // use Structure

In your case the correct mapping is在您的情况下,正确的映射是

void anpr_set_params(byte instance, SLPRParams slpr_params);

The mapping with long might appear to work on 64-bit non-Windows operating systems if you extracted the structure's pointer's peer value ( Pointer.nativeValue(params.getPointer() ). But it wouldn't be portable. Just pass the Structure and JNA handles the rest.如果您提取结构的指针的对等值( Pointer.nativeValue(params.getPointer() ),那么使用long的映射可能似乎适用于 64 位非 Windows 操作系统。但它不会是可移植的。只需传递结构和JNA 处理其余部分。

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

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