SWIG:从普通的C ++到工作的Wrapper

时间:2010-05-03 21:09:43

标签: java c++ swig

我一直在尝试为这个小小的C ++课程创建一个SWIG包装器,在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文件并运行
  6. 第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 个答案:

答案 0 :(得分:1)

根据您的操作,使用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

答案 1 :(得分:1)

我的问题是双重的;其中一个我理解(并且认为相当愚蠢),第二个我不愿但愿意和

首先,更改“java.library.path”对使用System.loadLibrary()时java实际看起来的位置没有影响。它不是很好,但使用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"