Libc SIGSEGV при вызове нативного метода из Java

Я пытаюсь, чтобы моя Java-реализация Purchase-SDK для покупок из приложения Amazon In-App Store осуществляла обратную связь с моим кодом C++ с помощью встроенного метода.

PurchasingObserver.java // выписка

public class PurchasingObserver
{
    //...

    private native void postEvent(int type, String jsonData);
    // called by each of the four event handler methods, data is non-null
    // also tried it as native synchronized
}

AmazonInAppPurchaseHandler.cpp // выдержка

static AmazonInAppPurchaseHandler* AmazonInAppPurchaseHandler::s_pInstance(0); // dumbleton

JNIEXPORT void JNICALL  _NativePurchasingObserverPostEvent(JNIEnv* pEnv, jobject obj, jint type, jstring jsonData)
// friend function
{
  assert(type >= 0);
  assert(type < AmazonInAppPurchaseHandler::kNumEventTypes); // event type is in range
  assert(pEnv != 0); // JNI environment is valid

  printf("Stuff from the native callback: %d, %p\n", type, jsonData); // never gets printed.

  int jsonDataLen(0);
  const char* pJsonDataUtfChars(0);
  if(jsonData != 0)
  {
    jsonDataLen = pEnv->GetStringUTFLength(jsonData);
    pJsonDataUtfChars = pEnv->GetStringUTFChars(jsonData, 0);
  }

  assert(s_pInstance != 0); // got AmazonInAppPurchaseHandler instance
  s_pInstance->DoCallback(type, jsonDataLen, pJsonDataUtfChars);

  pEnv->ReleaseStringUTFChars(jsonData, pJsonDataUtfChars);
}

static const JNINativeMethod karNativeMethod[] =
{
  { 
    "postEvent",
    "(ILjava/lang/String;)V",
    (void*)&_NativePurchasingObserverPostEvent
  }
};


AmazonInAppPurchaseHandler::AmazonInAppPurchaseHandler()
{
  assert(s_pInstance == 0); // is only instance
  s_pInstance = this;

  JNIEnv* pEnv(GetJNIEnv());
  assert(pEnv != 0); // got JNI environment

  jint  result(pEnv->RegisterNatives(cPurchaseObserver, karNativeMethod, 1));
  assert(AmazonInAppPurchaseHandler, result == 0); // successfully registered
}

AmazonInAppPurchaseHandler::~AmazonInAppPurchaseHandler()
{
  s_pInstance = 0;
}

Как только я делаю что-либо, генерирующее событие, происходит следующее: 1, обработчик события вызывается правильно, он регистрирует его. 2, он также регистрирует "Posting event...", последнюю вещь перед вызовом postEvent(). 3, программа падает в libc с SIGSEGV. (Это относится к моему приложению, но обратите внимание, что обратное имя dotcom усечено. Я не уверен, если это необычно.) 4, трассировка в C++ _NativePurchasingObserverPostEvent никогда не достигается.

Журнал:

12-05 10: 24: 47.380: D/com.mycompany.amazoninapp.PurchasingObserver@41970368 (4604): onGetUserIdResponse: (com.amazon.inapp.purchasing.GetUserIdResponse@4196cf98, requestId: "dcf8-7-012 ee9ae544f53d ", getUserIdRequestStatus:" SUCCESSFUL ", userId:" DefaultTestUser ")

12-05 10: 24: 47.380: D/com.mycompany.amazoninapp.PurchasingObserver@41970368 (4604): публикация события...

12-05 10: 24: 47.380: A / libc (4604): фатальный сигнал 11 (SIGSEGV) в 0x00000008 (код =1), нить 4604 (y.amazoninapp)

12-05 10: 24: 47.390: I / AmazonSDKTester (3529): отправка ответа об обновлении покупки ({"revokedSkus":[],"offset":"1354703087397","status":"SUCCESSFUL","requestId":"b9aee42e-4f50-42c4-8a12-ba9eb1d19155","делает ставку" ложь, "квитанции":[{"Код":"com.mycompany.amazoninapp.ENTI01","маркер":"eyJ0eXBlIjoiTk9OQ09OU1VNQUJMRSIsInNrdSI6ImNvbS5wbGF5ZXJ0aHJlZS5hbWF6b25pbmFw\ncC5FTlRJMDEifQ\ п", "ItemType":"ОЗАГЛАВЛЕННЫЙ"}],"идентификатор пользователя":"DefaultTestUser"})

Я прошел через итерации правильного определения имени класса JNI и строки сигнатуры метода (мы прошли UnsatisfiedLinkErrors); Я дважды проверяю нулевые строки. Остальная часть моего JNI работает нормально, интерфейс покупок в приложении Amazon отображается правильно. События гарантированно не генерируются до регистрации собственного метода.

Что является причиной аварии?

Спасибо за ваш вклад заранее.

2 ответа

Вы должны объявить вашу функцию как использующую C Соглашение о вызовах. Объявите это как extern "C" как в:

extern "C" void _NativePurchasingObserverPostEvent(JNIEnv* pEnv, jobject obj, jint type, jstring jsonData)

Попробуйте использовать javah создать заголовок, который вы #include в ваш C++ код, вместо того, чтобы писать прототип функции самостоятельно.

Другие вопросы по тегам