SWIG:来自 Plain C++到工作包装器

发布于 2024-08-31 07:59:02 字数 1387 浏览 6 评论 0原文

我一直在尝试为这个小小的 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文件并运行

步骤4和5给我带来了很多问题,从基本的(由于不在java路径中而未找到库“example”)到奇怪的(未找到库)即使 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 命令来配合它。

I've been trying to create a SWIG wrapper for this tiny little C++ class for the better part of 3 hours with no success, so I was hoping one of you out there could lend me a small hand. I have the following class:

#include <stdio.h>

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

#include "example.h"

Along with the implementation:

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;
}

I've read through the introduction page ( www.swig.org/Doc1.3/Java.html ) a few times without gaining a whole lot of insight into the situation. My steps were

  1. Create an example.i file
  2. Compile original alongside
    example_wrap.cxx (no linking)
  3. link resulting object files together
  4. Create a little java test file (see
    below)
  5. javac all .java files there and run

Well steps 4 and 5 have created a host of problems for me, starting with the basic ( library 'example' not found due to not being in java's path ) to the weird ( library not found even unless LD_LIBRARY_PATH is set to something, even if it's nothing at all). I've included my little testing code below

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!");
    }
}

Well, if anyone has navigated these murky waters of wrapping, I could not be happier than if you could light the way, particularly if you could provide the example.i and bash commands to go along with it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

双马尾 2024-09-07 07:59:02

根据您正在做什么,使用 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

Depending on what you are doing, it may be easier to use scipy.weave. See below for an example, it is fairly self explanatory. My experience with SWIG is that it works great, but passing around variables is a real 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
素手挽清风 2024-09-07 07:59:02

我的问题有两个方面:其中一个我理解(并且认为相当愚蠢),第二个我不理解,但愿意接受

首先,更改“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"

My problems stem two-fold; One of which I understand (and think is rather dumb), and the second which I don't but am willing to go with

First, changing "java.library.path" has no effect on where java actually looks when using System.loadLibrary(). It's not great, but it is slightly better to use System.load() along with the current directory. Unfortunately, the full name of the library must be known beforehand, which will wreak havoc with any cross-platform code. Why Java allows you to change this System Property without actually affecting anything befuddles me. Is there a better method without actually messing with $LD_LIBRARY_PATH or Windows PATH?

Secondly, it seems ld somehow isn't doing its job properly in linking, so instead I use g++ to link. Ie, instead of

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

I use

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

The resulting file no longer has any link problems (why?). Noticing both of these along with the following example.i got me through to working code:

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

%include "example.h"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文