gpt4 book ai didi

java - 让 SWIG 理解 char** 以便在 Java 中使用它

转载 作者:搜寻专家 更新时间:2023-10-31 01:52:39 25 4
gpt4 key购买 nike

我有以下三个文件:

sab1.hpp:

class CRectangle 

{
int x, y;

public:
void set_values (int,int);
void print(char **db);
int area ();
};

sab1.cpp:

#include <iostream>
#include "sab1.hpp"
using namespace std;

int CRectangle::area ()
{
return (x*y);
}

void CRectangle::set_values (int a, int b)
{
x = a;
y = b;
}

void CRectangle::print(char **db)
{
cout <<db[0];
}

int main ()
{
CRectangle rect;
char *a[] = {"Hi", "bye" } ;

rect.set_values (3,4);
cout << "area: " << rect.area();
rect.print(&a[0]);
return 0;
}

sab1.i :

%module Rec
%{
/* Includes the header in the wrapper code */
#include "sab1.hpp"
%}
class CRectangle {
int x, y;
public:
void set_values (int,int);
void print(char **db);
int area ();
};

我使用以下常用命令创建各种中间文件:

1) swig -c++ -java sab1.i

2) g++ -fpic -c sab1.cpp sab1_wrap.cxx -I/usr/lib/jvm/java-6-openjdk-i386/include/-I/usr/lib/jvm/java-6-openjdk- i386/包括/linux/

然后我使用这个创建一个共享库:g++ --shared sab1.o sab1_wrap.o -o libegs.so

然后我创建以下 Java 文件来访问 C++ 类的函数:

public class Test 
{
public static void main(String args[])
{
System.loadLibrary("egs");
CRectangle a = new CRectangle();
a.set_values(4,5);
System.out.println(a.area());
a.print("Hi");
}
}

当我编译 Java 文件 (javac -classpath . Test.java ) 时,出现以下错误:

Test.java:17: print(SWIGTYPE_p_p_char) in CRectangle cannot be applied to (java.lang.String)  a.print("Hi");
^

那么,我怎样才能让 Java 代码理解 char ** 变量呢?我曾尝试在 SWIG 接口(interface)文件 (sab1.i) 中创建类型映射,但无法正确理解。

在此先感谢您的帮助。

最佳答案

%module Rec
%include "various.i"

%apply char **STRING_ARRAY { char **db }

%include "sab1.hpp"

您链接到的文件 various.i 应该以这种方式工作,只需将它放在 SWIG 可以找到它的地方,在您的项目包含目录或 SWIG 包含路径中。

使用 %include 而不是 #include "sab1.hpp" 意味着我们不必复制我们想要包装的类的定义。 %apply 指令将 various.i 中的类型映射应用于名称为 dbchar** 类型的所有参数>。如果还有其他要包装的参数名称,请像这样添加它们:

%apply char **STRING_ARRAY { char **db, char **foo, char **bar }

如果你只想包装 所有 char** 类型的参数(不安全!),只需省略名称:

%apply char **STRING_ARRAY { char ** }

由于您的 C++ 代码期望该数组包含 2 个字符串,因此只要您从 Java 传递一个包含 2 个或更多 String 的数组,就应该没问题。类型映射将向数组添加第三个空指针,但您的 C++ 代码不会注意到。如果您传递的数组少于 2 个 String,您的 C++ 代码可能会崩溃。

如果您包装的任何 C++ 函数还返回一个字符串数组,那么您就有麻烦了。 SWIG 将尝试将它们转换回 Java 数组,但当它在数组中查找第三个元素时可能会崩溃(它将继续查找元素,直到找到空指针)。如果你不介意丢弃返回值,你可以这样做:

%module Rec
%include "various.i"

%typemap(jni) char **db = char **STRING_ARRAY;
%typemap(jtype) char **db = char **STRING_ARRAY;
%typemap(jstype) char **db = char **STRING_ARRAY;
%typemap(in) char **db = char **STRING_ARRAY;
%typemap(freearg) char **db = char **STRING_ARRAY;
%typemap(javain) char **db = char **STRING_ARRAY;

%include "sab1.hpp"

这将只应用类型映射中处理输入参数的部分。

关于java - 让 SWIG 理解 char** 以便在 Java 中使用它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12304806/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com