Заставить SWIG понимать char ** для использования его в Java

У меня есть следующие три файла:

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 / include / 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 (sab1.i), но я не могу правильно это выяснить.

Заранее спасибо за помощь.

2

Решение

%module Rec
%include "various.i"
%apply char **STRING_ARRAY { char **db }

%include "sab1.hpp"

Файл various.i который вы связали, должен работать таким образом, просто поместите его где-нибудь, где SWIG сможет его найти, в вашем каталоге include или SWIG include path.

С помощью %include вместо #include "sab1.hpp" означает, что нам не нужно копировать определение классов, которые мы хотим обернуть. %apply Директива применяет карту типов из various.i на все аргументы char** введите с именем db, Если есть другие имена аргументов, которые вы хотите обернуть, добавьте их так:

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

Если вы просто хотите обернуть все аргумент типа char** (небезопасно!), просто опустите имя:

%apply char **STRING_ARRAY { char ** }

Поскольку ваш код C ++ ожидает, что массив будет содержать 2 строки, тогда, пока вы передаете массив из 2 или более Stringс Java, это должно быть хорошо. Карта типов добавит третий нулевой указатель в массив, но ваш код C ++ не заметит. Если вы передаете массив с менее чем 2 Strings, вы, вероятно, сломаете ваш код 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"

Это будет применять только те части карты типов, которые имеют дело с входными аргументами.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]