4

我很难让 SWIG类型映射(javapackage)正常工作。我尝试制作一个简单版本的问题,即使这样似乎也失败了。

富.h:

#ifndef FOO_H
#define FOO_H

class Foo
{
public:
    Foo() {};
    int doSomething() { return 1 };
};

#endif

酒吧.h:

#ifndef BAR_H
#define BAR_H

#include "foo.h"

class Bar
{
public:
    Bar() {};
    int doSomething(Foo foo) { return foo.doSomething(); };
};

#endif

Foo.i

%module FooMod

%include "typemaps.i"
%include "stdint.i"

%{
#include "../header/foo.h"
%}

%include "../header/foo.h"

巴.i

%module BarMod

%import "Foo.i"

%typemap("javapackage") Foo, Foo *, Foo & "com.me.t.foo";

%include "typemaps.i"
%include "stdint.i"

%{
#include "../header/bar.h"
%}

%include "../header/bar.h"

使用以下命令运行这些:

swig -c++ -java -package com.me.t.foo -outdir ../../src/com/me/t/foo -o ../src/Foo.cpp Foo.i
swig -c++ -java -package com.me.t.bar -outdir ../../src/com/me/t/bar -o ../src/Bar.cpp Bar.i

我得到这个输出:

package com.me.t.bar;

public class Bar {
  private long swigCPtr;
  protected boolean swigCMemOwn;

  protected Bar(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  protected static long getCPtr(Bar obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }

  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (swigCPtr != 0) {
      if (swigCMemOwn) {
        swigCMemOwn = false;
        BarModJNI.delete_Bar(swigCPtr);
      }
      swigCPtr = 0;
    }
  }

  public Bar() {
    this(BarModJNI.new_Bar(), true);
  }

  public int doSomething(Foo foo) {
    return BarModJNI.Bar_doSomething(swigCPtr, this, Foo.getCPtr(foo), foo);
  }

}

BarModJNI.java:

package com.me.t.bar;

public class BarModJNI {
  public final static native long new_Bar();
  public final static native int Bar_doSomething(long jarg1, Bar jarg1_, long jarg2, Foo jarg2_);
  public final static native long Bar_getFoo(long jarg1, Bar jarg1_);
  public final static native void delete_Bar(long jarg1);
}

文件已正确生成,但请注意没有 import 语句,因此在任何一个 Bar Java 类中都找不到Foo 。这是一个简单的示例,但仅对 import 语句进行硬编码不是我的选择,因为生成的包含 C JNI 代码的源文件可能具有错误的“Foo”类文件位置。

这似乎是一个非常简单和常见的问题,所以,我想知道我是否遗漏了什么或者我做错了什么。

谢谢您的帮助!

4

3 回答 3

4

遇到同样的问题并找到答案,因此将其发布给社区。

您需要进行 3 项更改。

  1. 将导入语句添加到生成的代理类(Bar.java):

    // Bar.i
    %pragma(java) jniclassimports=%{
    import com.me.t.foo.Foo;
    %}
    
  2. 将导入语句添加到生成的 JNI 包装类 (BarModJNI.java):

    // Bar.i
    %typemap(javaimports) Bar %{
    import com.me.t.foo.Foo;
    %}
    
  3. 告诉 SWIG 创建Foo.getCPtr一个公共成员变量,因为 Bar 类会想要访问它:

    // Foo.i
    SWIG_JAVABODY_PROXY(public, public, SWIGTYPE)
    SWIG_JAVABODY_TYPEWRAPPER(public, public, public, SWIGTYPE)
    

参考:

于 2014-02-17T08:21:01.703 回答
1

只是对 Zbigniew 提供的答案的一些评论。我遇到了这篇文章中描述的同样的问题。我想澄清两点。

首先,在我看来,第 1 步是在 JNI 包装类(whateverJNI.java)中添加导入,而第 2 步是为特定类添加导入。

其次,第 2 步对我不起作用,而不是%typemap(javaimports) <class>我不得不使用%typemap(javaimports) SWIGTYPE. 坏事是它将导入添加到所有生成的 java 类,而不仅仅是所需的类。

最后,我仍然遇到 SWIG 在包装特定类型时无法识别导入的类并且它仍然使用SWIGTYPE_<type>而不是直接使用的问题<type>

于 2015-09-29T07:42:56.063 回答
0

我遇到了同样的问题。我通过写作解决了(您需要在 .i 文件中写入)

%typemap(javaimports) namespace::classname
%{
import com.yourcompany.yourapp.*;
%}

此代码仅生成您指定的类的导入语句。
注意:您必须指定本地命名空间,否则您的类将不会被看到!

示例:如果您的 C++ 代码如下所示:

namespace A{  
class MyPerfectClass{

};  
}

你需要写

%typemap(javaimports) A::MyPerfectClass
%{
import com.yourcompany.yourapp.*;
%}

如果要在所有 java 包装的类中添加这个 import 语句,则需要编写

%typemap(javaimports) SWIGTYPE
%{
import com.yourcompany.yourapp.*;
%}

对于 JNI Java 类:

%pragma(java) jniclassimports=%{
import com.yourcompany.yourapp.*;
%}

证明代码在这里:

package com.mycompany.myproject.A_package;

import com.mycompany.myproject.B_package.*;

public class MYCLASS{
  private transient long swigCPtr;
  protected transient boolean swigCMemOwn;

  public MYCLASS(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  public static long getCPtr(MYCLASSobj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }
  .
  . etc.

如果你有不止一门课,你可以继续:

%typemap(javaimports) A::MyPerfectClass , A::B::MyFantasticClass , MyNoNamespaceClass 

我已经用 SWIG 4.0 进行了测试,它可以工作。
我已经更改了证明代码上的包名和类名,因为我不能分享我的公司和类名。我希望这个答案对遇到同样问题的其他人有所帮助。

于 2020-02-05T10:56:06.867 回答