从 java 回调返回结构到 C++
Returning struct from java callback to c++
在我的软件应用程序中,我使用来自 Java 使用 JNA 的 C++ 本机库。我需要一个回调函数,它 return 是 C++ 的复杂 java 对象。
这可能是一个简单的问题,但我没有使用 C++ 或 JNA 的经验,我无法成功 return 将 java 对象转换为 C++。
我遇到的 JNA 回调函数的大多数示例都很简单,它们要么 return 什么都没有,要么 return 一个简单的本机类型。
我的本机代码如下所示
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;
}
Java代码:
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>
而不是预期的
In native function
In Java callback
returned int: 25
returned string: Hello World!
你能帮我弄清楚我做错了什么吗?非常感谢您的帮助。
此致,
H.
每个 JNA Structure
分配自己的内存,一旦超出范围就可能被 GC。
您需要让您的本机代码将内存传递给要填充的 Java 代码(而不是分配一个然后 returning 它),或者保持对 每个 Structure
从 Java 代码中 return 编辑以防止 GC。
您也可以尝试在 return 之前调用 Structure.write()
;通常 Java 会自动同步结构,但是当 return 从回调中调用结构时可能会出现错误。
在我的软件应用程序中,我使用来自 Java 使用 JNA 的 C++ 本机库。我需要一个回调函数,它 return 是 C++ 的复杂 java 对象。
这可能是一个简单的问题,但我没有使用 C++ 或 JNA 的经验,我无法成功 return 将 java 对象转换为 C++。
我遇到的 JNA 回调函数的大多数示例都很简单,它们要么 return 什么都没有,要么 return 一个简单的本机类型。
我的本机代码如下所示
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;
}
Java代码:
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>
而不是预期的
In native function
In Java callback
returned int: 25
returned string: Hello World!
你能帮我弄清楚我做错了什么吗?非常感谢您的帮助。
此致, H.
每个 JNA Structure
分配自己的内存,一旦超出范围就可能被 GC。
您需要让您的本机代码将内存传递给要填充的 Java 代码(而不是分配一个然后 returning 它),或者保持对 每个 Structure
从 Java 代码中 return 编辑以防止 GC。
您也可以尝试在 return 之前调用 Structure.write()
;通常 Java 会自动同步结构,但是当 return 从回调中调用结构时可能会出现错误。