Сбой сегментации Java JNIEnv - PullRequest
5 голосов
/ 27 июля 2011

Я нахожусь в процессе создания некоторого кода взаимодействия Java <-> .NET с использованием собственной библиотеки между ними, пока что дела идут довольно хорошо.

Однако по какой-то причине я не могу запустить какие-либо методыпод JNIEnv.

System::String^ JNIStringToNet(JNIEnv * env, jstring js)
{
    const char *buf = env->GetStringUTFChars(js, 0); // segfault

Теперь я могу передавать переменные туда-сюда и делать все другие виды связи, поэтому я полагаю, что я не инициализировал это правильно или что-то в этом роде.

Iзагружаю его так:

this.Lib = (LibHandler)Native.loadLibrary(this.Name, LibHandler.class);     

(я предпочитаю Native.loadLibrary, потому что, кажется, он позволяет мне делать больше с ним проще, например, совместное использование классов между несколькими библиотеками, отсоединение и повторное включение из JVMна лету).

Редактировать:

Серьезно любой метод:

std::cout << "Getting version:" << std::endl;
std::cout << env->GetVersion() << std::endl;

Получение версии:

(segfault)

Есть какие-нибудь идеи относительно того, что JNIEnv будет использовать для каждого метода?Это должно быть установлено JVM, правильно?

Edit 2:

Это приложение Java, которое вызывает библиотеку C ++, которая будет взаимодействовать с .NETбиблиотека (так что это библиотека C ++, скомпилированная CLR, если это имеет какое-то значение), чтобы ограничить любые внешние факторы, я даже не вызываю .NET DLL, а просто конвертирую строки, которые возвращаются (или, ну ... пытаемся).

Так, например, из Java:

this.Lib = (LibHandler)Native.loadLibrary(this.Name, LibHandler.class);
this.Lib.myCPPMethod(); // Segmentation fault during this call, JVM crashes.

Интересно, вызвал ли это CLR: отключил компиляцию clr и удалил все, что было связано с CLR, по-прежнему делает это.

Редактировать 3:

Получил дамп:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000000000000, pid=1596, tid=7248
#
# JRE version: 6.0_23-b05
# Java VM: Java HotSpot(TM) 64-Bit Server VM (19.0-b09 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  0x0000000000000000

Так что да, похоже, JVM не дает мне доступ к памяти по некоторым причинам.

Редактировать 4:

Фактический вызов:

JNIEXPORT jstring JNICALL Query(JNIEnv * env, jobject jobj, jstring start, jstring end)
{ 
    std::cout << "Getting version:" << std::endl;
    jint j = env->GetVersion();
    return jstring("test");
}

Редактировать 5:

Работаетс System.loadLibrary:

JNIEXPORT void JNICALL Java_LibTest_T(JNIEnv *env, jobject jobj)
{ 
    std::cout << "Getting version:" << std::endl;
    jint j = env->GetVersion();
    std::cout << j << std::endl;
}

Вывод:

java -Djava.library.path="(dir)\lib\64" EntryPoint
Getting version:
65542

Ack!Я имею в виду некоторый прогресс, но я не могу выгрузить библиотеки из JVM, которые загружены в System.loadLibrary, могу ли я?

Мне нужно иметь возможность отсоединить эти библиотеки от JVM и заменить их наВдобавок ко всему, все они должны «совместно использовать» один класс и иметь возможность быть привязанными к классу во время выполнения ... именно поэтому я решил использовать Native.loadLibrary.

В настоящее время я делаю это:

Загрузите DLL:

this.Lib = (LibHandler)Native.loadLibrary(this.Name, LibHandler.class);

Отцепите ее:

this.Lib = null;
Runtime.getRuntime().gc(); // Force the JVM to drop it immediately.

Класс I загружает их все в:

public interface LibHandler extends Library{ 
    void T();
}

Любой способ работыаналогично System.loadLibrary?

Редактировать 6:

Не стесняйтесь называть меня тупым, я использую JNA, NOT JNI, которыйэто совершенно другой и огромный источник моих проблем .... есть ли способ сделать это с JNI?Или я могу заставить JNIEnv зарегистрироваться в JNA как-нибудь?Я предполагаю, что смогу удалить JNI из библиотеки C ++ и сразу использовать wstrings?

Я вернусь с этим завтра.

1 Ответ

0 голосов
/ 28 июля 2011

Ну, я плохо себя чувствую.

Native.loadLibrary == JNA.

System.loadLibrary == JNI.

Цель JNA - не требовать каких-либо реальных знаний о среде JVM, чтобы вы могли запускать собственные библиотеки как есть, поэтому вместо jstring вы можете использовать char * ...

...