SWIG: от простого C ++ до рабочего Wrapper - PullRequest
3 голосов
/ 04 мая 2010

Я пытался создать оболочку SWIG для этого крошечного маленького класса C ++ большую часть 3 часов, но безуспешно, поэтому я надеялся, что один из вас сможет протянуть мне небольшую руку. У меня есть следующий класс:

#include <stdio.h>

class Example {
public:
    Example();
    ~Example();
    int test();
};

#include "example.h"

Вместе с реализацией:

Example::Example()
{
    printf("Example constructor called\n");
}

Example::~Example()
{
    printf("Example destructor called\n");
}

int Example::test()
{
    printf("Holy shit, I work!\n");
    return 42;
}

Я несколько раз прочитал страницу введения (www.swig.org/Doc1.3/Java.html), не разбираясь в ситуации. Мои шаги были

  1. Создать файл example.i
  2. Компиляция оригинала вместе example_wrap.cxx (без ссылок)
  3. связывает полученные объектные файлы вместе
  4. Создайте небольшой тестовый файл Java (см. ниже)
  5. javac все файлы .java и запустите

Ну, шаги 4 и 5 создали для меня массу проблем, начиная с базового («пример» библиотеки не найден из-за отсутствия пути java) до странного (библиотека не найдена, даже если LD_LIBRARY_PATH не установлен на что-то , даже если это вообще ничего). Я включил свой маленький тестовый код ниже

public class test2 {
    static {
        String libpath = System.getProperty("java.library.path");
        String currentDir = System.getProperty("user.dir");
        System.setProperty("java.library.path", currentDir + ":" + libpath);

        System.out.println(System.getProperty("java.library.path"));

        System.loadLibrary("example");
    }

    public static void main(String[] args){
        System.out.println("It loads!");
    }
}

Ну, если бы кто-нибудь прошел через эти мутные воды обертывания, я не мог бы быть счастливее, чем если бы вы могли осветить путь, особенно если бы вы могли предоставить команды example.i и bash, чтобы согласиться с ним.

Ответы [ 2 ]

1 голос
/ 04 мая 2010

Мои проблемы проистекают в два раза;Одна из них, которую я понимаю (и считаю довольно глупой), а вторая, которую я не понимаю, но с которой согласен

Во-первых, изменение «java.library.path» не влияет на то, где на самом деле находится Javaвыглядит при использовании System.loadLibrary ().Это не очень хорошо, но немного лучше использовать System.load () вместе с текущим каталогом.К сожалению, полное имя библиотеки должно быть известно заранее, что может нанести ущерб любому кроссплатформенному коду.Почему Java позволяет вам изменять это Системное Свойство, фактически не затрагивая меня.Есть ли лучший способ, не связываясь с $ LD_LIBRARY_PATH или Windows PATH?

Во-вторых, кажется, что ld почему-то не справляется со своей задачей, поэтому вместо этого я использую g ++ для ссылок.Т.е. вместо

ld -G example.o example_wrap.o -o libexample.so

я использую

g++ example.o example_wrap.o -o libexample.so

Полученный файл больше не имеет проблем со связью (почему?).Заметив оба этих примера вместе со следующим примером, я получил рабочий код:

/* File: example.i */
%module test
%{
#include "example.h"
%}

%include "example.h"
1 голос
/ 04 мая 2010

В зависимости от того, что вы делаете, может быть проще использовать scipy.weave. Ниже приведен пример, это довольно очевидно. Мой опыт работы с SWIG заключается в том, что он прекрасно работает, но передача переменных - это настоящая PITA.

import scipy.weave

def convolve( im, filt, reshape ):
height, stride = im.shape
fh,fw = filt.shape
im    = im.reshape( height * stride )
filt  = filt.reshape( fh*fw )
newIm = numpy.zeros ( (height * stride), numpy.int )
code  = """
int sum=0, pos;
int ys=0, fys=0;
for (int y=0; y < (height-(fh/2)); y++) {
  for (int x=0; x < (stride-(fw/2)); x++) {
    fys=sum=0;
    pos=ys+x;

    int th = ((height-y) < fh ) ? height-y : fh;
    int tw = ((stride-x) < fw ) ? stride-x : fw;

    for (int fy=0; fy < th; fy++) {
      for (int fx=0; fx < tw; fx++) {
        sum+=im[pos+fx]*filt[fys+fx];
      }
      fys+=fw;
      pos+=stride;
    }
    newIm[ys+x] = sum;
  }
  ys+=stride;
}
"""
scipy.weave.inline(code,['height','stride','fh','fw','im','filt','newIm'])

if reshape:
  return newIm.reshape(height,stride )
else:
  return newIm
...