Я нахожусь в процессе создания некоторого кода взаимодействия 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?
Я вернусь с этим завтра.