java - 如何从 native 函数按值返回?

标签 java jnr

我使用 Visual Studio 2017 编译了以下 C++ 方法:

extern "C" __declspec( dllexport )
Info* __stdcall GetInfo(InfoProvider* infoProvider)
{
   static_assert(std::is_pod<Info>::value, "Must be Plain Old Data in order to be safely copied between DLL boundaries");

   Info info = new Info();
   Info->data1 = infoProvider->data1;
   Info->data2 = infoProvider->data2;

   return info;
}

在 Java 代码中,它由 Java Native Runtime 使用具有以下签名的接口(interface)方法映射:

Info GetInfo(Pointer infoProvider);

final class Info extends Struct {

    public final Signed32 data1;

    public final Signed32 data2;

    public R2VInfo(final Runtime runtime) {
        super(runtime);

        data1 = new Signed32();
        data2 = new Signed32();
    }
}

有效。

上面的C++方法导致内存泄漏,所以我想改成按值返回结果:

extern "C" __declspec( dllexport )
Info __stdcall GetInfo(InfoProvider* infoProvider)
{
   static_assert(std::is_pod<Info>::value, "Must be Plain Old Data in order to be safely copied between DLL boundaries");

   Info info{};
   Info.data1 = infoProvider->data1;
   Info.data2 = infoProvider->data2;

   return info;
}

我使用相同的 Java JNR 映射:

Info GetInfo(Pointer infoProvider);

但它不起作用 - 访问冲突。调用 native 方法,但有一些未处理的指针值。

JNR中如何按值返回?

最佳答案

JNI 围绕旧的纯 K&R C 构建,以与所有可用的编译器兼容。从函数返回结构是在 C89 中引入的,并且在很晚的时候与 C++ 标准一起完全实现。今天,仍然可以在许多 java 友好环境(如小型设备或 sim 卡)中找到这种旧的 C 编译器。所以我不认为 JNI 会升级到 C89 甚至 C99。

对于您的情况,我建议编写一个额外的 C 代码来处理库函数的调用。代码可以通过两种方式实现:

  1. 对于 Info* __stdcall GetInfo(InfoProvider* infoProvider),您应该编写如下自由函数:
extern "C" __declspec( dllexport )
void __stdcall FreeInfo(Info* info)
{
   static_assert(std::is_pod<Info>::value, "Must be Plain Old Data in order to be safely copied between DLL boundaries");

   delete info;
}
  1. 对于 Info __stdcall GetInfo(InfoProvider* infoProvider),您应该编写一个包装器:
extern "C" __declspec( dllexport )
void __stdcall GetInfo(InfoProvider* infoProvider, Info* info)
{
   static_assert(std::is_pod<Info>::value, "Must be Plain Old Data in order to be safely copied between DLL boundaries");

   Info infoProvider = GetInfo(infoProvider);
   info->data1 = infoProvider.data1;
   info->data2 = infoProvider.data2;
}

关于java - 如何从 native 函数按值返回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56129984/

相关文章:

java - 让耳朵部署以编程方式将自身标记为失败

java - JMeter 是否完全支持 NTLM 身份验证?

java - jnr-ffi : Is there a generation tool from header files to java code

java - 如何在 jnr ffi 中使用结构体和结构体

java - 如何在 Intellij IDEA 中构建和运行 Storm Topology

java - Kotlin 中的错误但仅使用 Java - 类 kotlin.reflect.jvm.internal.FunctionCaller$FieldSetter

java - 导入libgdx项目到eclipse时出错

java - JNR-FFI 如何从指针到指针读取结构数组

java - 如何使用 java jnr 推断 clib 结构

java - java 中的 Fuse 文件系统 - JVM 错误双重释放或损坏