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

Я пытаюсь, чтобы моя Java-реализация SDK для покупок из приложения Amazon In-app PurchasingObserver поддерживала обратную связь с моим кодом 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. (Это относится к моему заявлению, но обратите внимание, что обратное имя доткома урезано. Я не уверен, если это необычно.)
4, трассировка в C ++ _NativePurchasingObserverPostEvent никогда не достигается.

Журнал:

12-05 10: 24: 47,380:
D/com.mycompany.amazoninapp.PurchasingObserver@41970368 (4604):
onGetUserIdResponse:
(com.amazon.inapp.purchasing.GetUserIdResponse@4196cf98, requestId:
«dcf8e712-078b-4d47-9533-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»: [], «смещение»: «1354703087397», «статус»: «Successful», «RequestID»: «b9aee42e-4f50-42c4-8a12-ba9eb1d19155», «делает ставку» ложь «квитанции» : [{ «Код»: «com.mycompany.amazoninapp.ENTI01», «маркер»: «eyJ0eXBlIjoiTk9OQ09OU1VNQUJMRSIsInNrdSI6ImNvbS5wbGF5ZXJ0aHJlZS5hbWF6b25pbmFw \ ncC5FTlRJMDEifQ \ п», «ItemType»: «ОЗАГЛАВЛЕННОЙ»}], «идентификатор пользователя»: «DefaultTestUser»})

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

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

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

1

Решение

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

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

Другие решения

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

0

По вопросам рекламы [email protected]