Как добавить аннотации Java в JNI SWIG API?

1

Мы используем SWIG для создания JNI API между API C++ и Java в Android.

Например, предположим, что наш класс 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 может быть пустым, и методы get & set могут получать/возвращать пустую String (автоматически сгенерированный код JNI ведет себя так, как ожидается в этом случае, и позволяет использовать jstring или null).

У меня вопрос: может ли SWIG добавлять аннотации, такие как @Nullable или @NonNull для соответствия API C++ (если нам нужно предоставить "подсказки" для 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.

Теги:
kotlin
swig

1 ответ

1

Дайте вашему примеру класс C++ в файле с именем test.h, вы можете сгенерировать оболочку 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;
%}
  • 0
    Это решение работает, но у него есть два недостатка: 1) Это очень специфично, мне нужно будет добавить %typemap с @Nullable для каждого типа, который я использую (и если я хочу добавить @NonNull это будет еще большей болью ). 2) Код не компилируется, так как отсутствует импорт для android.support.annotation .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню