dswigwordsize64时,c++-swig java将int64\t转换为jlong

vu8f3i0k  于 2021-07-12  发布在  Java
关注(0)|答案(3)|浏览(563)

上下文

我有一个带重载的c++代码 int 以及 int64_t 我需要 Package 成java


# include <cstdint>

int foo(int param);
int foo(int64_t param);
};

还有这大口

%{

# include <cstdint>

%}

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

%ignore "";
%rename ("foo") foo(int);
%rename ("foo") foo(int64_t);

%include "foo.hpp";

合同通用条款

使用gcc int64时,将定义为long int

grepc -rn "typedef.*INT64_TYPE" /lib/gcc
/lib/gcc/x86_64-linux-gnu/9/include/stdint-gcc.h:43:typedef __INT64_TYPE__ int64_t;

然后

gcc -dM -E -x c++ /dev/null | grep __INT64

# define __INT64_TYPE__ long int

所以我用 -DSWIGWORDSIZE64 避免 Package 器类型错误的问题

grep "int64" -C 1 /usr/local/share/swig/4.0.1/stdint.i 

# if defined(SWIGWORDSIZE64)

typedef long int        int64_t;

# else

typedef long long int       int64_t;

# endif

到目前为止还不错(至少在python和csharp中是这样),但是在java中。。。

大口java

在java中,swig swig似乎 Package 了c++ long int 到c Package 器 int (同时将2^64截断为2^32…)参考:http://www.swig.org/doc4.0/swigdocumentation.html#java_default_primitive_type_mappings src公司:https://github.com/swig/swig/blob/master/lib/java/typemaps.i
所以这两种方法将有相同的原型->我目前的问题
afaikjava/typemaps.i或java.swg支持 SWIGWORDSIZE64 切换。。。

测试协议

为了重现这个问题(我使用的是swig4.0.1)

mkdir -p gen
swig -DSWIGWORDSIZE64 -I. -c++ -java -o gen/foo_java_wrap.cc -package com.google.Foo -module main -outdir gen foo.i

观察

foo.hpp:9: Warning 516: Overloaded method baz(int64_t) ignored,
foo.hpp:8: Warning 516: using baz(int) instead.

cat gen/main.java
...
package com.google.Foo;

public class main {
  public static int baz(int param) {
    return mainJNI.baz__SWIG_0(param);
  }

}

预期

cat gen/main.java
...
package com.google.Foo;

public class main {
  public static int baz(int param) {
    return mainJNI.baz__SWIG_0(param);
  }
  public static int baz(long param) {
    return mainJNI.baz__SWIG_1(param);
  }
}

那么我该如何处理这个问题呢?
谢谢
编辑:您可以在此处找到此示例:https://github.com/mizux/swig_java (您可以单击徽章查看日志/文件)

pzfprimi

pzfprimi1#

一个难看的解决方法是不使用 SWIGWORDSIZE64 ,所以 int64_t 将是typedef to long long 它将被打印到 jlong . 请参见:http://www.swig.org/doc4.0/swigdocumentation.html#java_default_primitive_type_mappings
但是,在c++warp文件中 long long 需要修补的(例如,使用后期处理) sed -i -e 's/long long/int64_t/g' )否则编译失败,因为 long long 类型不同于 int64_t (又名 long int )

jchrr9hc

jchrr9hc2#

您可以尝试提供自己的类型Map。

%include "stdint.i;"

# ifdef SWIGWORDSIZE64

%define PRIMITIVE_TYPEMAP(TYPE, JNITYPE, JTYPE)
%clear TYPE;
%typemap(jstype) TYPE "JTYPE";
%typemap(javain) TYPE "$javainput";
%typemap(jtype) TYPE "JTYPE";
%typemap(jni) TYPE "JNITYPE";
%typemap(in) TYPE %{ $1 = ($1_ltype)&$input; %}
%typemap(freearg) TYPE "";
%typemap(out) TYPE %{ $result = $1; %}
%typemap(javaout) TYPE %{ return $jnicall; %}

%enddef // PRIMITIVE_TYPEMAP

PRIMITIVE_TYPEMAP(long int, jlong, long);
PRIMITIVE_TYPEMAP(unsigned long int, jlong, long);

# undef PRIMITIVE_TYPEMAP

# endif // SWIGWORDSIZE64
hgb9j2n6

hgb9j2n63#

既然你想重复使用 long long 类型Map:


# ifdef SWIGWORDSIZE64

%define PRIMITIVE_TYPEMAP(NEW_TYPE, TYPE)
%clear NEW_TYPE;
%apply TYPE { NEW_TYPE };
%enddef // PRIMITIVE_TYPEMAP

PRIMITIVE_TYPEMAP(long int, long long);
PRIMITIVE_TYPEMAP(unsigned long int, long long);

# undef PRIMITIVE_TYPEMAP

# endif // SWIGWORDSIZE64

相关问题