我有 C++ 代码,正在尝试使用 SWIG 提供 Java 绑定。
struct meters_t : public boost::units::quantity<boost::units::si::length> {};
我希望尝试将
meters_t
的所有引用替换为 double
或 Java.lang.Double
。
我在我的 SWIG 界面
.i
文件中尝试了以下操作:
%typemap(jstype) meters_t "java.lang.Double"
%typemap(jtype) meters_t "java.lang.Double"
%typemap(jni) meters_t "jdouble"
...
// Duplicated for const, const&, &
%ignore meters_t
%include "my_include.h"
但是我目前遇到类型转换错误
error C2440: 'type cast': cannot convert from 'meters_t *' to 'jdouble'
error C2440: 'type cast': cannot convert from `jdouble` to `meters_t *`
有人有任何建议来纠正这个问题吗?我很快就失去了将
meters_t
转换为简单 double
的想法是可能的:/
更新: 我还添加了以下内容
%typemap(javain) meters_t "$javainput"
这使得可以构建 Java 绑定,但是当我尝试使用 Java 绑定时(在不同的
struct
上,将 meters_t
作为构造函数参数),它会立即抛出错误
A fatal error has been detected by the Java Runtime Environment
EXCEPTION_ACCESS_VIOLATION
更新2.0
我现在已经将
meters_t
SWIG 包裹起来。我的新问题是一个带有 boost 默认参数的类,我遇到了难以捉摸的 Syntax error in input(3).
错误
Foo(meters_t meters = meters_t{ 0.0 * boost::units::si::meters });
您已经开始使用 typemaps 走上正确的轨道。这些对于 C++ 和 Java 之间的类型转换至关重要。但这些错误表明 SWIG 在
meters_t
和 jdouble
之间自动转换时遇到问题。
您可能需要提供 custom 类型映射来显式处理此转换。您需要为 SWIG 提供一种方法来了解如何将
meters_t
转换为 jdouble
,反之亦然。
尝试并为
%typemap(in)
实施 %typemap(out)
和 meters_t
。这些类型映射将定义从 C++ 传递到 Java 时如何将 meters_t
对象转换为 Java double
,反之亦然。
SWIG 对解析复杂的默认参数]的支持有限。一种解决方案是简化 SWIG 接口文件中的默认参数,或者提供没有默认参数的构造函数的重载版本,以便 SWIG 进行包装。
在您的 SWIG 接口文件中,实现类型映射:
%typemap(in) meters_t {
// Code to convert from jdouble to meters_t
}
%typemap(out) meters_t {
// Code to convert from meters_t to jdouble
}
// For the constructor issue
%ignore Foo::Foo(meters_t);
%extend Foo {
Foo() {
return new Foo(meters_t{0.0 * boost::units::si::meters});
}
}
您需要根据
meters_t
如何与double
相互转换来填写转换逻辑。
关于“
Code to convert from jdouble to meters_t
”,从Java转换为C++时,您将收到一个Java double
(在C++ JNI代码中表示为jdouble
)。您需要将其转换为 meters_t
对象。meters_t
可以从 double
构造或分配,则类型映射可能如下所示:
%typemap(in) meters_t {
$1 = meters_t($input * boost::units::si::meter);
}
在此类型图中:
$1
是 C++ 参数的占位符(在本例中为 meters_t
)。$input
表示来自 Java 的输入(a jdouble
)。$input * boost::units::si::meter
从 Java double 构造一个 meters_t
对象,假设 meters_t
可以通过这种方式初始化。对于“
Code to convert from meters_t to jdouble
”:
从 C++ 转换为 Java 时,您需要从
double
对象中提取 meters_t
值:
%typemap(out) meters_t {
$result = (jdouble)$1.value();
}
在此类型图中:
$1
是 C++ meters_t
对象的占位符。$result
是您要映射到的 Java 类型的 JNI 表示形式(在本例中为 jdouble
)。$1.value()
是一种从 double
对象中提取 meters_t
值的假设方法或方式。您需要将其替换为从 meters_t
类型中提取数值的实际方法或途径。确保
meters_t
可以由 double
构造而成,并具有将其值提取为 double
的方法。如果没有,您将需要调整代码以适应meters_t
的实际界面。boost::units::si::meter
是合适的转换单位。如有必要,请根据您的具体实施meters_t
进行调整。