【发布时间】:2011-11-17 20:01:49
【问题描述】:
我的 SWIG 接口文件(包含在头文件中)中有一个 C 函数,它当前返回一个 char *,SWIG 使用该函数为 fetchFromRow 方法生成 String Java 返回类型。我想知道如果我在 C 端将返回更改为 void *,SWIG 在 Java 端会做什么? C fetchFromRow 函数返回一个结构 (sockaddr_in)、String 或 int。如何设置我的 SWIG 接口文件以支持此功能?有没有办法让生成的 Java fetchFromRow 具有 Object 的返回类型,以便我可以在 Java 端进行强制转换?
C 代码:
extern char *
fetchFromRow(struct row_t *r_row,
type_t type);
extern void *
fetchFromRow(struct row_t *r_row,
type_t type);
当我在头文件(包含在 SWIG 接口文件中)中使用 void * 生成方法时,我得到了一个带有 SWIGTYPE_p_void 返回类型的 java 方法。关于如何处理的任何想法?
痛饮文件:
%module Example
%include "typemaps.i"
%include "stdint.i"
%include "arrays_java.i"
void setPhy_idx(uint32_t value);
%include "arrays_java.i"
void setId(unsigned char *value);
%{
#include "Example1.h"
#include "Example2.h"
#include "Example3.h"
#include "Example4.h"
%}
%rename setLogFile setLogFileAsString;
%inline %{
void setLogFileAsString(const char *fn) {
FILE *f = fopen(fn, "w");
setLogFile(f);
}
%}
%typemap(jstype) void* "java.lang.Object"
%typemap(javaout) void* {
long cPtr = $jnicall;
Object result = null;
if (type == type_t.TYPE_CATEGORY) {
result = void2int8(cPtr);
}
return result;
}
%newobject fetch(struct result_row_t *result_row, type_t type, int32_t *length);
%inline %{
uint8_t void2int8(jlong v) {
return (intptr_t)v;
}
%}
%apply char * { unsigned char * };
%apply char * { const void * }
%apply int32_t { int32_t * }
int createKey(const void* secret, int secret_len, const sdr_id_t *id, unsigned char key[20], int key_len);
session_t* createSession(const char* addr, int ort, const char *ddr, int rt, const der_id_t *id, unsigned char key[20], int key_len);
%apply int32_t *OUTPUT { int32_t *length }
%ignore createKey;
%ignore setLogFile;
%ignore ecreateSession;
%include "Example1.h"
%include "Example2.h"
%include "Example3.h"
%include "Example4.h"
%pragma(java) jniclasscode=%{
static {
try {
System.loadLibrary("Example");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. \n" + e);
System.exit(1);
}
}
%}
调用 fetch 的 Java 代码:
{
//only type_t param shown here for simplicity
Object category = Example.fetch(result_row, type_t.TYPE_CATEGORY, length);
System.out.println("category=" + aLevel.toString());
System.out.println("category=" + ((Short)aLevel).intValue());
System.out.println("category=" + ((Short)aLevel).toString());
//all 3 Sys outs show same value but when called again each show same value but different than the first execution
}
我试图用 SWIG 替换的 C 代码包装器。这用于从 Java 调用,但现在我尝试直接调用 fetch(伪代码):
char *
wrapFetch(struct row_t *result_row, type_t type)
{
int8_t *int8_valp = NULL;
switch (attribute) {
case TYPE_CATEGORY:
int8_valp = fetch(
result_row, attribute, &length);
if (length > 0 && int8_valp != NULL) {
snprintf(smallbuf, sizeof(smallbuf), "%u", *int8_valp);
return strdup(smallbuf);
} else {
return NULL;
}
}
【问题讨论】:
-
略有不同。它关于支持 void C 返回类型
-
这很棘手,但我认为可行。基本上,您需要在
type_ts 和它们所代表的“真实”类型之间进行映射,以使 Java 方面的演员表可行。我有一个类似 Python 的示例,希望本周末能够将其转换为 Java。 -
@MiguelGarcia - 我不认为这是重复的,因为在这种情况下
void*被用作缓冲区。
标签: java java-native-interface swig