Re[20]: JNI Attach
От: Pavel Dvorkin Россия  
Дата: 06.11.24 11:54
Оценка:
Здравствуйте, ·, Вы писали:

PD>> ·>Классы в dll? Гы, такой гемор. Обычно из юзабельного только extern "C".

PD>> Да нет, ничего особенного. Вполне можно использовать.
·>Можно, но только когда у тебя один большой проект, собирается одной версией компилятора с идентичным списком ключей. И то тебе придётся преобразовывать std::string в CString из BSTR и ещё хз чего. В случае плагинов, как у топикстартера, когда dll-и приходят из разных источников от разных вендоров, то упс.

Ну это проблемы ТС. Он о том, что это за плугины и даже о том, сам они их пишет или нет, ничего не говорил, да и не надо было.
А так да, одной версий компилятора. Впрочем, если в проекте окажется просто DLL, сделанная другой версией компилятора, то проблем может быть тоже достаточно даже без классов в DLL.

PD>> Собственно говоря, класс есть класс независимо от того, лежит он в EXE или DLL

PD>> А как, собственно, делать иначе, если некий класс нужен в нескольких project из этого solution ? Дублировать его ?
·>Если нужен реюзабельный компонент, то оборачивать в extern "C".

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

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


PD>> ·>Я не знаю что может означать "jar загружается". Есть classpath — места где ищутся классы. И это вовсе не обязательно должны быть jar (который просто обычный zip-архив). Классы могут грузится и из обычной директории, из на лету сгенерённого массива байтов и даже из сети.

PD>> Означать может просто "подключить все классы из этого архива".
·>Что значит "подключить класс"?

Так в следующей строчке объяснение, оно теперь чуть ниже. Выделю.

PD>> Иными словами, сделать то же самое, что делается при прописывании dependency на него в pom.xml. Только в рантайме, а не статически.
·>Ну так и с dll — всё так же. При запуске приолжения dll-ки времени сборки проекта подгружаются так же как обычно и jar-ки в pom.xml. А динамической подгрузкой надо звать LoadLibrary и GetProcAddress и мучиться с источниками. Всё то же, всё так же.

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

PD>> Так же как LoadLibrary означает "загрузить все, что в ней есть"

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

Нет, не только. Сначала маппируется DLL на АП процесса, а потом действительно вызов DLLMain. Собственно, вызов DLLMain к загрузке отношения не имеет. Она будет вызываться и при загрузке, и при запуске/удалении потока. Это просто некое место для настройки одному из 4 событий.

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


new ClassLoader может загрузить все классы из этого jar ? Если да — то нет вопроса. Но, как я понимаю, нет ?

И вообще, в чем, собственно, концептуальная разница между DLL в .net и jar в Java ? ИМХО ее практически нет. И там и тут набор доступных извне классов. Ну а то, что там их упаковали в MZ/PE-файл, а тут в zip-файл — это дело вкуса. Смотреть что есть в этом jar/zip, конечно, проще, но и содержимое DLL посмотреть тоже не очень сложно.

PD>> ·>В качестве аналогии можно сказать так: dll — соответсвует java-классу, а jar — это LD_LIBRARY_PATH. Вот и попробуй представь что может означать "загрузка LD_LIBRARY_PATH".

PD>> Ну даже чисто формально DLL не есть один класс (или namespace), а целая коллекция средств — например, WinSock или GDI. Ты же не скажешь, что GDI32.DLL — это один класс ?
PD>> И уж в любом случае это один файл, а не path
·>Ну я же говорю, что это аналогия, а не точное соответствие.

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


Да бога ради. LoadLibrary может взять из любого места. Загрузка DLL из памяти тоже возможна.
With best regards
Pavel Dvorkin
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.