- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我的SWIG接口文件(包含在头文件中)中有一个C函数,该函数当前返回一个char *,SWIG使用该char *为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);
%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);
}
}
%}
{
//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
}
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;
}
}
最佳答案
如果您为返回类型定义类型层次结构,并将基类用作fetchFromRow
的返回类型,则这可能会更容易。 (事实证明,解决方案并不像我最初想象的那么容易,甚至还有an example in the documentation!This question also applies to Java+SWIG。)尽管您可以按照自己的要求做,但我还是举了一个简单的例子来说明要点。
我在这里使用的示例在test.h
中有一个简单的接口(声明和定义使这里的内容更简单):
struct type1 {
type1(int foo) : foo(foo) {}
int foo;
};
struct type2 {
type2(double bar) : bar(bar) {}
double bar;
};
// TYPE3 is int32_t, TYPE4 is const char*
typedef enum { TYPE1, TYPE2, TYPE3, TYPE4 } type_t;
void* fetch(type_t type) {
switch(type) {
case TYPE1:
return new type1(101);
case TYPE2:
return new type2(1.111);
case TYPE3:
return (void*)(-123); // One way of returning int32_t via void*!
case TYPE4:
return (void*)("Hello world"); // Cast because not const void*
default:
return NULL;
}
}
enum
值配对。为简单起见选择了这些。只要您具有可以应用的合适的类型映射,它们就可以是您想要的任何东西。 (如果要专门使用
sockaddr_in
,则应应用
my answer to your previous question中的类型映射,以专门包装
sockaddr_in
)。
fetch
,它创建一种类型并通过
void *
返回它。这说明了您在问题中提出的要求。
fetch
的棘手之处在于,SWIG没有直接的方法来推断
void*
指针返回之前的内容。我们需要使用有关
type_t
参数含义的高级知识,为SWIG提供一种更具体地了解类型是什么的方法。
test.i
,该文件以常用的模块材料开头:
%module test
%{
#include "test.h"
%}
fetch
函数,我们需要找到一种明智的方式来在Java端公开最接近
void*
的东西。在这种情况下,我认为
java.lang.Object
是返回类型的一个不错的选择,它在这里可以很好地近似
void*
。
%typemap(jstype) void* "java.lang.Object"
fetch
的返回类型。 (尽管我们没有使用
%typemap(jtype)
更改生成的JNI中介的返回类型,但仍然像以前一样默认为
long
)。
%typemap(javaout) void* {
long cPtr = $jnicall;
Object result = null;
if (type == type_t.TYPE1) {
result = new type1(cPtr, $owner);
}
else if (type == type_t.TYPE2) {
result = new type2(cPtr, $owner);
}
else if (type == type_t.TYPE3) {
result = void2int(cPtr);
// could also write "result = new Integer(void2int(cPtr));" explicitly here
}
else if (type == type_t.TYPE4) {
result = void2str(cPtr);
}
return result;
}
%newobject fetch(type_t type);
type_t
来决定使用哪种类型。 (我不是100%满意地通过名称来引用此类型,即直接使用
type
,但似乎没有更好的方法来访问在
javaout
typemap中调用函数的参数)
$owner
)对于内存管理很重要,它指出谁拥有分配,并且我们希望将所有权转让给Java以避免泄漏。它的值由
%newobject
指令确定。
void*
转换为
int32_t
和
String
案例的更有意义的类型。我们为此提供
%inline
,以要求SWIG同时包装和定义它:
%inline %{
int32_t void2int(jlong v) {
return (intptr_t)v;
}
const char *void2str(jlong v) {
return (const char*)v;
}
%}
jlong
是因为在接口的Java端,所有指针都表示为
long
。它可以确保函数与JNI调用返回的函数完全兼容,而不会失去精度(在某些平台上
jlong
可能是
long long
)。基本上,存在这些函数可以通过较少的手动工作来实现从通用(
void*
)到C端的特定转换。 SWIG在这里为我们处理所有类型。
%include
(我们希望将其包装起来,这是最简单的方法),以及一些导致库自动加载的代码:
%include "test.h"
%pragma(java) jniclasscode=%{
static {
try {
System.loadLibrary("test");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. \n" + e);
System.exit(1);
}
}
%}
swig -Wall -java -c++ test.i
javac *.java
g++ -Wall -Wextra test_wrap.cxx -shared -I/usr/lib/jvm/java-6-sun/include -I/usr/lib/jvm/java-6-sun/include/linux/ -o libtest.so
public class main {
public static void main(String[] argv) {
Object o1 = test.fetch(type_t.TYPE1);
Object o2 = test.fetch(type_t.TYPE2);
Object o3 = test.fetch(type_t.TYPE3);
Object o4 = test.fetch(type_t.TYPE4);
if (!(o1 instanceof type1)) {
System.out.println("Wrong type - o1");
}
else {
System.out.println("o1.getFoo(): " + ((type1)o1).getFoo());
}
if (!(o2 instanceof type2)) {
System.out.println("Wrong type - o2");
}
else {
System.out.println("o2.getFoo(): " + ((type2)o2).getBar());
}
if (!(o3 instanceof Integer)) {
System.out.println("Wrong type - o3");
}
else {
System.out.println("o3.intValue(): " + ((Integer)o3).intValue());
}
if (!(o4 instanceof String)) {
System.out.println("Wrong type - o4");
}
else {
System.out.println("o4: " + (String)o4);
}
}
}
test.i
,但是为了方便起见,我还放置了
test.i on my site的副本。
关于java - SWIG支持void * C返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8173497/
作为作业的一部分,我正在尝试创建一个用户级线程库,如 pthreads。 为了处理线程之间的上下文切换,我使用了“swapcontext”函数。在使用它之前,我必须使用“makecontext”函数创
我是一名初级 C++ 程序员,我正在 Linux 机器上编程。 我遇到了这个错误: cannot convert ‘void* (Network::*)(void*)’ to ‘void* (*)(v
我知道,例如 void *(*myFuncName)(void*) 是一个函数指针,它接受并返回 void*。 这是一个有两个参数的指针吗?void 指针是该类型的另一个返回 void* 和 void
所以我被告知它们彼此几乎相同 void function1 (void(func)(int), int arg){ func(arg); } void function2 (void(*fun
我目前正在 GNU Radio 上开发一个 bloc,我想使用一个线程。该线程用于从 UDP 套接字获取数据,因此我可以在我的 GNU Radio 集团中使用它。 “一般工作”功能是执行所有信号和数据
我正在尝试在主函数中创建一个线程并通过我的线程调用另一个类的函数。 在 main.cpp 中: SocketHandler *callserver; pthread_t thread1; pthrea
我正在使用pthread 为我自己实现线程类。所以,我创建了 Thread 类如下: class Thread { public: Thread() { } virtual void*
我收到上述警告并理解它,但就是不知道如何解决它。我的代码在下面,但基本上我所做的是在结构中存储一个函数指针,并在我从 main.c 调用的另一个函数中初始化该结构。当我将代码与默认函数(即 free(
在我的 android 应用程序中,我在 doInBackground 中执行一些操作通过扩展 AsyncTask类(class)。 (我在这个类中执行任何 UI 都没用) 这是正确使用 AsyncT
我在 GNU 编译器集合中使用 C。所以我需要将函数指针传递给一个函数。现在有两种我想要处理的可接受的函数指针原型(prototype): void function(void); 和 void fu
我正在尝试使用“CameraManager”类创建一个新线程,但出现以下错误: cannot convert '*void(CameraManager:: * )(void*) to void*( *
我想构建一个可以隐藏线程创建的“IThread”类。子类实现“ThreadMain”方法并使其自动调用,如下所示: class IThread { public: void BeginThre
我不明白什么 void (**)(void *, const char *) /* ^^ why are there 2 asterisks here? 意思是,它是一个指向函数的指针,但我失败
我必须将“risposta”类型的参数“r”发送到函数 RispostaServer。编译器给我:invalid conversion void*(*)() to void*(*)(void*) 这是
所以我目前正在使用,或者至少正在尝试编写一个利用 this C pthread threadpool library. 的程序 值得注意的是 thpool.h 中的以下函数: int thpool_a
我正在尝试使用 void* 指针将不同的对象存储在一个全局表中。问题是如何取回 void* 对象。如果我有一个公共(public)基类,比如 Object ,我总是可以将 void* 指针存储为 Ob
我是一名 C 程序员(在 linux 上),但现在我有一个关于 C++ 的项目,并且有一个问题。 这里是示例代码 g_action.sa_sigaction = (void(*)(int,siginf
class Scoreget{ private: //some variables public: Scoreget(){ //
这个问题在这里已经有了答案: Is there a difference between foo(void) and foo() in C++ or C? (4 个答案) func() vs fun
我正在尝试使用 SDL 和 SDL_Mixer 为音频创建一个 C++ 应用程序,并且正在尝试遵循 this教程。但是,使用 SDL_Mixer 的 Mix_HookMusicFinished() 不
我是一名优秀的程序员,十分优秀!