java - Swig 类型映射 java 对象

标签 java swig

我正在尝试通过 swig 为这两个 C++ 函数生成 java 绑定(bind)

C++ 函数

void SetUserData(void* data);
void* GetUserData() const;

在java方面我希望它看起来像这样

setUserData(Object object);
getUserData() //return java.lang.Object

我希望 void* 指针指向我传递给它的任何 java 对象。在我的 swig 文件中,我尝试添加这些行

//swig file
%typemap(jstype) void* "java.lang.Object";
%apply Object {void*};

我收到编译错误: b2Fixture.swig(22):警告453:无法应用(对象)。没有定义类型映射。我不知道如何为此制作类型映射。有什么想法吗?

最佳答案

您可能想做:

%apply jobject { void* };

因为 %apply 将一种 C++ 类型上定义的类型映射复制到另一种 C++ 类型。 Object 是一种 Java 类型,而不是 C++ 类型,因此没有任何要复制的类型映射。另一方面,jobject 是 JNI 等效项。

此外,假设您希望拥有“正常”GC 语义(即不需要保留您传入的任何数据),您需要做更多的工作,例如:

%module test

%{
#include "test.hh"
%}

%apply jobject { void * };

%typemap(in) void * {
  void *old = getData();
  if (old) JCALL1(DeleteGlobalRef, jenv, (jobject)old);
  $1 = JCALL1(NewGlobalRef, jenv, $input);
}

%typemap(out) void * {
  $result = (jobject)($1);
}

%include "test.hh"

这将为您的数据创建一个新的全局引用,这可能是阻止 GC 释放数据的唯一因素。

给定一个头文件:

void setData(void *);
void *getData();

和一个实现:

#include "test.hh"

namespace {
  void *d = nullptr;
}

void setData(void *d) {
  ::d = d;
}

void *getData() {
  return d;
}

这足以允许:

public class run {
  public static void main(String[] argv) {
    System.loadLibrary("test");
    Object example = "HELLO";
    test.setData(example);
    System.out.println(test.getData());
  }
}

正确工作。

正如所写,这些类型映射非常丑陋 - 它们会影响 void *所有使用。因此,如果您确实使用了此功能,您可能需要再次使用 %apply%clear 以限制其影响。您还可以在头文件中命名参数,并使用它来限制应用类型映射的位置。

关于java - Swig 类型映射 java 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26110908/

相关文章:

python - 将 C++ 对象传递给 Python

Python 和 SWIG - 单个 .pyd (.so) 中的多个模块

java - InsertAPN() 方法不写入 APN 设置 - Android 2.3.6

java - 检查匹配的标签

java - tinyMCE 不仅替换了文本区域,还替换了整个表单

java - 使用 AspectJ 查找 Java 中未使用的代码

javascript - 在 Mac OS X 上使用 SWIG 为 javascript 编译 C++

python - FANN Python 绑定(bind)失败

java - 如何在swig中使用同一个接口(interface)生成两个代理类

java - 如何使用 WebServiceTemplate 发送 SOAP 请求?