- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我为以下 C++ 代码创建了 JNI 包装器。
add.h
class MyClass
{
public:
int add(int x, int y, int &z);
int sub(int x, int y);
};
上面提到的代码就是.h文件
添加.cpp
int MyClass::add(int x, int y, int &sum)
{
sum=x+y;
return 0;
}
int MyClass::sub(int x, int y)
{
return x - y;
}
swig.i
%module algo
%{
#define SWIG_FILE_WITH_INIT
#include "add.h"
%}
%include "arrays_java.i"
%include "typemaps.i"
%include "add.h"
对于上面提到的 .cpp 文件,我需要生成 JNI 包装器并将其用于 Java 代码。当我尝试执行 swig 命令时,我得到了 SWIGTYPE_p_int.java 文件和 JNI 文件。谁能帮我解决这个问题?
最佳答案
要包装 C++“通过非常量引用返回”函数,有很多选项可供选择。简而言之,您可以执行以下操作之一:
%extend
提供一个返回的重载。 (可选择隐藏原件)SWIGTYPE_p_int
。 (可选择在 Java 内部构建重载)OUTPUT
类型映射通过数组获得按引用语义传递我将在此处展示每个选项的示例。
%extend
提供重载这里的基本思想是,我们将在此处编写一个全新的重载,SWIG 对其进行简单包装。使用下面的 %extend
语法,我们可以创建一个新的、仅包装器的重载,它使用临时存储值,然后在一切顺利时返回它。
%module algo
%{
#define SWIG_FILE_WITH_INIT
#include "add.h"
#include <exception>
%}
%extend MyClass {
int add(int x, int y) {
int z;
const int result = $self->add(x,y,z);
if (0 == result) return z;
throw std::exception();
// TODO: use SWIG's exception support
}
}
%ignore MyClass::add(int,int,int&); // Optional: hide the original overload
%include "add.h"
由于原始返回的 int 似乎指示函数本身的成功/失败,我们可以更自然地将其映射到 Java 中的异常。 (此处略去,详见我在XXX的回答)
这个解决方案的效果和上一个类似,只是实现方式不同。在这里,我们使用带有 numinputs=0
的 in
类型映射来设置一个我们可以在调用发生时使用的临时变量 (tmpz
) .然后 out 类型映射只检查来自真实函数调用的返回代码,argout 类型映射将 tempoary 复制到结果中。我在这里包含了比实际需要更多的类型映射,因为碰巧 z
和现有函数返回的类型相同,但如果不是这种情况,我们将需要它们。
%module algo
%{
#define SWIG_FILE_WITH_INIT
#include "add.h"
#include <exception>
%}
// These aren't actually needed here because the fuction already returns in
%typemap(jni) int MyClass::add "jint";
%typemap(jtype) int MyClass::add "int";
%typemap(jstype) int MyClass::add "int";
%typemap(javaout) int MyClass::add {
return $jnicall;
}
// These create a temporary and map it to the return value for us
%typemap(argout) int& z {
$result = (jint)tmpz$argnum;
}
%typemap(out) int MyClass::add {
if ($1 != 0) {
throw std::exception();
// TODO: exceptions as in other examples
}
}
%typemap(in,numinputs=0) int& z (int tmpz) {
$1 = &tmpz;
}
%include "add.h"
在这里,我们将使用 SWIG 的 cpointer.i
库来帮助我们处理 SWIGTYPE_p_int
对象,并为我们的 Java 用户透明地执行此操作。为此,我们使用 javacode 类型映射为 z
创建了一个临时变量,然后将其传递给原始 SWIG 生成的函数(可以将其设为私有(private)以隐藏它)。与其他示例一样,我们可以通过抛出异常来处理返回值指示错误的情况,尽管这次已经是 Java 代码在执行抛出,这稍微简单一些。
%module algo
%{
#define SWIG_FILE_WITH_INIT
#include "add.h"
%}
%include "cpointer.i"
%pointer_class(int,IntPointer);
%typemap(javacode) MyClass %{
public int add(int x, int y) {
IntPointer z = new IntPointer();
int ret = this.add(x,y,z.cast());
if (ret != 0) throw new Exception();
return z.value();
}
%}
%javamethodmodifiers MyClass::add(int,int,int&) "private" // Optional
%include "add.h"
OUTPUT
类型映射这在功能上与之前的解决方案非常相似,不同的是我们使用数组而不是使用 SWIG 提供的辅助类型来处理 int 指针,并在底层利用 Java 的“按引用传递数组”语义来实现同样的结果。
%module algo
%{
#define SWIG_FILE_WITH_INIT
#include "add.h"
%}
%include <typemaps.i>
%apply int *OUTPUT { int & z };
%typemap(javacode) MyClass %{
public int add(int x, int y) {
int[] z = new int[1];
int ret = this.add(x,y,z);
if (ret != 0) throw new Exception();
return z[0];
}
%}
%javamethodmodifiers MyClass::add(int,int,int&) "private"
%include "add.h"
您可以使用 %inline
添加其他类型。然后欺骗 SWIG 使用它而不是 int&
引用。只要我们允许隐式转换就可以了。
%module algo
%{
#define SWIG_FILE_WITH_INIT
#include "add.h"
%}
%inline %{
struct IntWrapper {
int value;
// Enable transparent conversion for the SWIG argument
operator int&() {
return value;
}
};
%}
class MyClass
{
public:
int add(int x, int y, IntWrapper& z); // lie to SWIG, but we'll make it up later with implict conversion
int sub(int x, int y);
};
//%include "add.h" // Don't do this now because we need the lie above
与前面的示例一样,我们可以选择通过重载和方法修饰符的使用对 Java 用户隐藏此实现细节。
关于java - Swig 类型映射将变量地址作为参数传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44568507/
我正在制作一个 C++ 库的包装器,以便它可以从 Java 中使用,我正在用 Swig 做这个。 我面临的是我有一个类(class) SomeClass ,它有一些重载的方法( someMethod
我有许多要在 SWIG 中重命名的类。我的大部分类(class)看起来像这样some_class ,我想将其重命名为 SomeClass .这很简单: %replace("%(camelcase)s"
PyPy 有一些 compatibility limitations ,尤其是关于 CPython C API。 我用 QuickFix预编译的 SWIG 绑定(bind)附带的包,我正在考虑将它与
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 9年前关闭。 Improve this q
使用 SWIG 生成接口(interface)模块时,生成的 C/C++ 文件包含大量静态样板函数。因此,如果想通过在同一个应用程序中使用许多单独编译的小接口(interface)来模块化 SWIG
我正在应用 SWIG 手册中有关嵌套类的解决方法,该部分使用全局内部类。在这里,我将向您展示一个类似于手册中的版本,但为您尽可能地简化了。我还必须将内联定义 {} 添加到 method(),因为没有它
我有一个现有的库 (JPhysX),它是原生 C++ 库 (PhysX) 的 Java 包装器。 Java 库使用 SWIG 生成的类型,例如 com.jphysx.SWIGTYPE_p_NxStre
有没有办法动态向下转换 swig 对象的 swig 代理? 这样做的原因是为了模拟 C++ 向下转换,但纯粹来自 python。例如,典型的 C++ 用法是 MyBase* obj = new MyB
我在远程服务器上工作,所以我在本地安装了 swig,使用 -prefix=/home/user/directory。 我有一个来自同事的 makefile,其中包含以下命令: swig $(SWIG_
据我所知,在用于将 c++ 文件编译为 python 扩展模块的 .i 文件中,我们可以添加一些 python 代码,如下所示(来自 example for adding additional pyt
我的 Swig 文件 (.i) 中有以下代码: %extend vgSofa::handler::VertexShape { vgd::Shp createVSWithNode( so
我有一个用 swig 包装的类的 C++ 代码。我无法修改代码或包装。在 python 中,我使用 ctypes 拥有一个指向所述 C++ 类的实例的指针。如何围绕该指针创建一个 swig 包装器?
我开始掌握 SWIG 的窍门,SWIG 的最新版本 (v3.0) 似乎可以处理我开箱即用所需的一切,包括 C++11 功能,但我遇到了麻烦开始在我的导演类(class)中使用 shared_ptr。
我正在使用 javacode 类型映射来添加一些附加函数来代替 SWIG 生成的函数。我想删除 SWIG 为 unsigned char mac[6]; 生成的默认 getter 和 setter(p
我正在使用 SWIG 为我的 C 库生成 Python 语言绑定(bind)。我已经设法构建了绑定(bind)和导出的数据结构,但在使用该库时我不得不跳过一些障碍。 例如,C 头文件的数据类型和函数原
我最近在node-js应用程序中从jade模板引擎切换到了swig。在使用jade时我使用了命令 jade.render('/sample.jade',{obj:object});渲染模板并传递对象。
我在我的 python 代码中发现了瓶颈,尝试了 Psycho 等。然后决定编写一个 c/c++ 扩展来提高性能。 在 swig 的帮助下,您几乎不需要关心参数等。一切正常。 现在我的问题是:swig
由于 SWIG 无法解析 __attribute__((packed))在我想包装的一些 C 结构上,我通过放置一个 #define __attribute__(x) 在我的.i文件。 这什么时候会来
我有一个包含 C++ header 的 SWIG 文件。 痛饮文件: %module my_module %{ #include "my_c_file.h" %} %include "my_c_fil
我正在尝试学习如何使用 SWIG,并且想知道我是否正在执行一些不需要执行的额外步骤。我目前有文件 Dog.cpp、Dog.h 和 Dog.i。我正在尝试使用 SWIG 包装 Dog.cpp 以便在 P
我是一名优秀的程序员,十分优秀!