Re[21]: JNI Attach
От: · Великобритания  
Дата: 06.11.24 12:34
Оценка: :)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD> то проблем может быть тоже достаточно даже без классов в DLL.

...
PD> Ну это порой легче сказать, чем сделать. Есть какая-то иерархия классов, с виртуальными методами, попробуй ее обернуть в extern "C". Я не говорю, что вообще невозможно, но проблем будет намного больше. А потом однажды к этой иерархии добавится еще один наследник и станет совсем хорошо. А если этот наследник понадобится почему-то разместить в другой DLL или в EXE, то станет очень весело
Именно, поэтому твоё "Не знаю, почему в java столь усложнили динамическую загрузку кода.". Ответ очевидный: "ничего не усложнили, всё очень просто".

PD> Ну и опять же — C++ все-таки legacy язык, в него классы были добавлены, когда его из C сделали. А вот в C# прекрасно импортируются классы, потому что кроме классов, там ничего и нет.

Ну а как думаешь с кого c# содрал все идеи? Правда хреновенько содрал...

PD> ·>Что значит "подключить класс"?

PD> Так в следующей строчке объяснение, оно теперь чуть ниже. Выделю.
Ну так не класс подключается же, а просто classpath прописывается, аналог LD_PATH. Я тебе который раз объясняю.

PD> Динамическая загрузка DLL мало чем отличается от статической.

В java вообще ничем не отличается. Если посмотришь устройство "java.exe" он просто создаёт самый обыкновенный class loader, ищет в нём указанный класс и дёргает у него метод по имени "main".

PD> То же проецирование DLL в АП процесса, то же разрешение импортов. Только делается в рантайме, а не при запуске. А GetProcAddress к LoadLibary отношения не имеет, это потом. Я спокойно могу сделать DLL с одними ресурсами и/или внутренним кодом (в DLLMain), в которой не будет ни одного экспорта.

Ну так и loadClass можешь не дёргать, а брать ресурсы через getResource.

PD> ·>Под "загрузить" ты, наверное, имеешь в виду "вызвать DllMain". Потом всё равно придётся выковыривать части по строковым именам используя GetProcAddress.

PD> Нет, не только. Сначала маппируется DLL на АП процесса, а потом действительно вызов DLLMain.
Это уже невидимая кухня как конкретно реализован LoadLibary унутре.

PD> Собственно, вызов DLLMain к загрузке отношения не имеет.

У тебя этот параграф напрямую противоречит следующему:
PD> Она будет вызываться и при загрузке, и при запуске/удалении потока. Это просто некое место для настройки одному из 4 событий.
Именно. Вот теперь объясни что же по-твоему должна делать эта твоя "загрузка jar".

PD> ·>LoadLibrary — соответсвует new ClassLoader, а GetProcAddress — loadClass().

PD> new ClassLoader может загрузить все классы из этого jar ? Если да — то нет вопроса. Но, как я понимаю, нет ?
ЕЩЁ РАЗ. Что значит "загрузить все классы"? Это бессмысленный вопрос.
Когда зовёшь loadClass напрямую (аналог GetProcAddress) ты достаёшь некий известный ожидаемый класс из заданных путей для поиска. Потом его можешь инстанциировать. Вот в этот момент VM смотрит что для инстанциации нужно. Напрмер, она рекурсивно дёргает loadClass для родительских классов, для типов параметров методов, вызывает статические инициализаторы для глобальных переменных и т.д, и т.п.

PD> И вообще, в чем, собственно, концептуальная разница между DLL в .net и jar в Java ? ИМХО ее практически нет.

DLL в .net это индуские перепевы jar в Java. Речь первоначально шла о C++.

PD> ·>ClassLoader позволяет хитрые манипуляции, полностью контролируя загрузку каждого класса. Примерно как допустим ты дёргаешь функцию в GDI32, а это что-то где-то внутре хочет дёрнуть другую функцию, а твой кастомный ClassLoader может взять его из другого места или даже пропатчить байткод на лету.

PD> Да бога ради. LoadLibrary может взять из любого места.


Ты не понял. Допустим в GDI32 у тебя есть
void func1() {func2();}
void func2() {print "hello";}

И ты делаешь
lib = LoadLibrary("GDI32");
f = GetProcAddr("func1");
f();//напишет "hello"

так вот ClassLoader позволяет резолвить имена как угодно. "func1" возьмётся из GDI32, а "func2" подставится из GDI33 и с пропатченным байт-кодом.


PD> Загрузка DLL из памяти тоже возможна.

Из RAM Drive? Шутишь?
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.