将结构从Java回调返回到C ++

时间:2018-09-26 20:40:19

标签: java c++ jna

在我的软件应用程序中,我正在使用JNA从Java使用C ++的本机库。我需要一个将复杂的Java对象返回给C ++的回调函数。

这可能是一个简单的问题,但是我没有使用C ++或JNA的经验,并且无法成功将Java对象返回到C ++。

我为JNA回调函数遇到的大多数示例都很简单,要么不返回任何内容,要么返回简单的本机类型。

我的本​​机代码如下所示

style="display: block"

Java代码:

typedef const char* SMC_String;
int doNativeProcessing(SMC_String identifier, SMC_String lastName, SMC_String firstName)

typedef struct SimpleStruct
{
  int myInt;
  SMC_String myString;
} SimpleStruct;

typedef SimpleStruct* (*GetSimpleStruct_Callback)(SMC_String identifier);
...

// function that gets called from Java
int doNativeProcessing(SMC_String identifier, SMC_String lastName, SMC_String firstName)
{
  cout << "In native function" << endl;
  ...do some processing...
  callMyCallback();
  return 0;
}

// function that calls the callback 
void callMyCallback()
{
  SimpleStruct *retSimpleStruct = GetSimpleStruct_Callback("id");
  cout << "returned int: " << retSimpleStruct->myInt << endl;
  cout << "returned string: " << retSimpleStruct->myString << endl;
}

运行应用程序时,输出为

public class SimpleStruct extends Structure {
  public static class ByReference extends SimpleStruct implements Structure.ByReference
  {}

  public SimpleStruct() {
    super();
  }

  @Override
  protected List<String> getFieldOrder() {
    return Arrays.asList("myInt", "myString");
  }

  public int myInt;
  public String myString;
}
...
public class GetSimpleStructCB implements Callback {
    public SimpleStruct.ByReference callback(final String requestId) {
      System.out.println("In Java callback");

      final SimpleStruct.ByReference retVal = new SimpleStruct.ByReference();
      retVal.myInt = 25;
      retVal.myString = "Hello World!";
      return retVal;
    }
}

public static void main(String[] args) {
    nativeLibrary = (NativeLibrary) Native.loadLibrary("my_native_dll", NativeLibrary.class);
    nativeLibrary.doNativeProcessing("id", "Doe", "John");
}

而不是预期的

In native function
In Java callback
returned int: 0  
returned string: <blank value>  

您能帮我弄清楚我做错了什么吗?非常感谢您的帮助。

关于,

1 个答案:

答案 0 :(得分:0)

每个JNA Structure分配自己的内存,一旦超出范围,它们可能会立即进行GC处理。

您需要使本机代码将内存传递给要填充的Java代码(而不是分配一个内存并返回它),或者保持对 every Structure的强烈引用Java代码返回的代码可以防止产生GC。

您还可以尝试在返回之前致电Structure.write();通常,Java会自动同步结构,但是从回调返回结构时,这样做可能会出错。