SWIG (Java):如何调用带有 void* out 参数的函数?
SWIG (Java): How can I call a function with a void* out parameter?
背景
我正在使用 C++ 代码库为 Android 开发一个实时通信应用程序。我使用 SWIG 生成一个 JNI 桥,以从 Java 访问本机代码。为了跟踪活动呼叫,void*
用作句柄(它指向包含有关正在进行的呼叫的信息的地址)。以下函数头是如何使用它的示例:
void initiateCall(void** callHandleRef);
void closeCall(void* callHandle);
initateCall
获取一个 void**
,分配一个结构并将其地址(作为 void*)写入 callHandleRef
。它作为一个“输出”参数工作,因为您将它作为参数传递并期望向它写入一些内容。当 closeCall
被调用时,原始指针被传递,允许 C++ 库访问与该特定调用关联的数据。
问题描述
我想从 Java 调用 initiateCall
和 closeCall
,使用 SWIG 生成执行此操作所需的 JNI 代码。然而。 SWIG 分别生成类型“SWIGTYPE_p_p_void”和“SWIGTYPE_p_void”,我无法按照上述方式使用它们。如何设置我的 SWIG 接口文件以允许我执行此操作?
Flexo 对这个问题的评论对我有用,如 所示。这是我的解决方案,或多或少 copy-pasted 来自他们的回答。
C++ 头文件(call.h):
typedef void* CALL_HANDLE;
int initiateCall(const char* name, CALL_HANDLE* handle);
int closeCall(CALL_HANDLE handle);
SWIG 接口(call.i):
%module bridge
%include <cpointer.i>
%pointer_class(CALL_HANDLE, inst_ptr);
%javamethodmodifiers initiateCall "private";
%pragma(java) modulecode=%{
public static SWIGTYPE_p_void initiateCall(String name) {
inst_ptr ptr = new inst_ptr();
final int err = initiateCall(name, ptr.cast());
if (0 != err) {
// Throw error or something like that
}
return ptr.value();
}
%}
%include "include/call.h"
extern int initiateCall(const char* name, CALL_HANDLE* handle);
extern int closeCall(CALL_HANDLE handle);
主要 activity (MainActivity.kt):
class MainActivity : AppCompatActivity() {
private lateinit var callHandle: SWIGTYPE_p_void
fun call(name: String) {
callHandle = bridge.initiateCall(name)
}
fun hangup() {
bridge.closeCall(callHandle)
}
}
背景
我正在使用 C++ 代码库为 Android 开发一个实时通信应用程序。我使用 SWIG 生成一个 JNI 桥,以从 Java 访问本机代码。为了跟踪活动呼叫,void*
用作句柄(它指向包含有关正在进行的呼叫的信息的地址)。以下函数头是如何使用它的示例:
void initiateCall(void** callHandleRef);
void closeCall(void* callHandle);
initateCall
获取一个 void**
,分配一个结构并将其地址(作为 void*)写入 callHandleRef
。它作为一个“输出”参数工作,因为您将它作为参数传递并期望向它写入一些内容。当 closeCall
被调用时,原始指针被传递,允许 C++ 库访问与该特定调用关联的数据。
问题描述
我想从 Java 调用 initiateCall
和 closeCall
,使用 SWIG 生成执行此操作所需的 JNI 代码。然而。 SWIG 分别生成类型“SWIGTYPE_p_p_void”和“SWIGTYPE_p_void”,我无法按照上述方式使用它们。如何设置我的 SWIG 接口文件以允许我执行此操作?
Flexo 对这个问题的评论对我有用,如
C++ 头文件(call.h):
typedef void* CALL_HANDLE;
int initiateCall(const char* name, CALL_HANDLE* handle);
int closeCall(CALL_HANDLE handle);
SWIG 接口(call.i):
%module bridge
%include <cpointer.i>
%pointer_class(CALL_HANDLE, inst_ptr);
%javamethodmodifiers initiateCall "private";
%pragma(java) modulecode=%{
public static SWIGTYPE_p_void initiateCall(String name) {
inst_ptr ptr = new inst_ptr();
final int err = initiateCall(name, ptr.cast());
if (0 != err) {
// Throw error or something like that
}
return ptr.value();
}
%}
%include "include/call.h"
extern int initiateCall(const char* name, CALL_HANDLE* handle);
extern int closeCall(CALL_HANDLE handle);
主要 activity (MainActivity.kt):
class MainActivity : AppCompatActivity() {
private lateinit var callHandle: SWIGTYPE_p_void
fun call(name: String) {
callHandle = bridge.initiateCall(name)
}
fun hangup() {
bridge.closeCall(callHandle)
}
}