我们正在使用SWIG在Android中的C ++ API到Java之间创建JNI API。
例如,假设我们的C ++类是:
class TestAnnotation {
public:
void setMessage(char * message);
char * getMessage();
private:
char* message = nullptr;
};
SWIG生成这个自动生成的Java类:
public class TestAnnotation {
...
public void setMessage(String message) {
myJNI.TestAnnotation_setMessage(swigCPtr, this, message);
}
public String getMessage() {
return myJNI.TestAnnotation_getMessage(swigCPtr, this);
}
}
正如您所看到的,message
可以为null,并且get和set方法可以接收/返回null String
(在这种情况下,JNI自动生成的代码的行为与预期相同,并允许使用jstring
或null
)。
我的问题是:SWIG是否能够添加像@Nullable
或@NonNull
这样的注释来匹配C ++ API(如果我们需要向SWIG提供“提示”,那也可以)。
因此,在这种情况下,所需的自动生成的Java API将是:
public class TestAnnotation {
...
public void setMessage(@Nullable String message) {
myJNI.TestAnnotation_setMessage(swigCPtr, this, message);
}
@Nullable
public String getMessage() {
return myJNI.TestAnnotation_getMessage(swigCPtr, this);
}
}
这很重要,因为我们将这个Java API与Kotlin一起使用,并且缺少注释使得使用Kotlin智能功能变得更加困难。
在名为test.h的文件中提供示例C ++类,您可以使用以下语法生成带有所需注释的Java包装器:
%module test
%javamethodmodifiers TestAnnotation::getMessage() %{
@Nullable
public%};
%typemap(jstype) char *message "@Nullable String";
%include "test.h"
考虑到命名主要集中在其他用例上,这有点反直觉,但仍然是完全合理的用法。
您当然可以通过不在其中命名参数(例如%typame(jstype) char * "..."
)来使输入的类型图不那么具体。
并且您将要使用另一个类型映射来设置导入:
%typemap(javaimports) TestAnnotation %{
import android.support.annotation;
%}
哪个可以更通用:
%typemap(javaimports) SWIGTYPE %{
import android.support.annotation;
%}