?

Log in

No account? Create an account
   Journal    Friends    Archive    Profile    Memories
 

Детская радость - morfizm


Jan. 26th, 2018 01:32 am Детская радость

Мне удалось запустить MessageBox!

Untitled


...из Scala :)

Потратил весь вечер.

Сначала я погуглил, как вызывают нейтив код из Java/Scala. Есть JNA и JNI. Первый удобнее, последний на пару порядоков быстрее. Десятичных порядков. Конечно, мне захотелось то, что быстрее.

Потом я долго разбирался с JNI. У меня наотрез отказывался загрузиться USER32.DLL, он его типа не может найти. Думал, что C:\Windows\System32 не в путях. Мне не хотелось добавлять путь аргументы JVM - целый час искал, как прописать его в путях через рантайм. Нашёл один грязный хак. Но он не работал... Потом плюнул и решил добавить аргументы в build.sbt. Они тоже не работали. Потом выяснилось, что и аргументы JVM, указанные напрямую, не работают. Оказалось, что System.LoadLibrary нужно давать просто имя библиотеки, USER32, без .DLL.

Потом оказалось, что JNI так просто не работает. Нельзя написать заголовок функции, объявить его @native, подгрузить библиотеку и пошлó. Нет, не пошлó! Оказывается, JNI работает только если написать специальный враппер на плюсах. Тут я схватился за голову, и решил пожертвовать перформансом ради удобства. Чёрт с ним, пусть будет JNA.

JNA - красавчик, и на нём можно писать примерно такой или такой код. Пришлось потрахаться с настройками SBT, потому что com.sun.jna.platform.win32 в упор не хотел импортироваться, не смотря на то, что com.sun.jna подлинкован правильно. Оказалось, что он лежит не в com.sun.jna, а в "net.java.dev.jna" % "jna-platform".

В общем, можно написать import com.sun.jna.platform.win32.User32.{ INSTANCE => User32 }, и там в User32 всё будет, все интерфейсы как часть уже нативной для Скалы библиотеки, со скаловскими объектами Pointer, HWND, WString... Но тут очередной облом. Именно MessageBox туда не включён. Но, на счастье, JNA позволяет подгружать библиотеку и генерить скалавский прокси динамически (теперь понятно, почему он медленный!). Примеры, конечно же, только на Java, потому, видимо, я первый извращенец, вызывающий WinAPI на Scala. Пришлось ещё ломать голову, как эти примеры переводить на человеческий язык. То бишь, скалавский. Конечный результат выглядит примерно так:
package dima.apps
import com.sun.jna.{ Library, Native, WString }
object Example {
  trait u32 extends Library {
    def MessageBoxW(whnd: Int, text: WString, caption: WString, flags: Int)
  }
  def main(args: Array[String]): Unit = {
    val lib = Native.loadLibrary("user32", classOf[u32]).asInstanceOf[u32]
    lib.MessageBoxW(0, new WString("Test"), new WString("Test"), 0)
  }
}
Ну и ещё две строчки в build.sbt:
libraryDependencies += "com.sun.jna" % "jna" % "3.0.9"
libraryDependencies += "net.java.dev.jna" % "jna-platform" % "4.5.1"
Ура!

17 comments - Leave a commentPrevious Entry Share Next Entry

Comments:

From:birdwatcher
Date:January 26th, 2018 10:24 am (UTC)
(Link)
Красота! В едином подходе совмещены быстродействие Скалы и самоверифицируемость С.
From:morfizm
Date:January 26th, 2018 11:00 am (UTC)
(Link)
Oh, lol!!! :)
From:andreyvo
Date:January 26th, 2018 10:47 am (UTC)
(Link)
Диме секс не нужен, у него и так разнообразная половая жизнь со скалой и JNI
From:morfizm
Date:January 26th, 2018 11:01 am (UTC)
(Link)
Это не relationship, это casual encounter ;) Я же всего один вечер потрахался.
From:natpy
Date:January 26th, 2018 12:22 pm (UTC)
(Link)
И сразу заработал себе PTSD :)
From:li111
Date:January 26th, 2018 07:26 pm (UTC)
(Link)
Молодец!
А зачем, это было важно?
From:morfizm
Date:January 26th, 2018 09:21 pm (UTC)
(Link)
О! Наконец-то вопрос по существу :)

Я же делаю переезд на новый компьютер, соответственно, навожу порядок в файлах. Их так много, и там такой бардак, что мне давно уже нужны (и сейчас эта потребность обострена) дополнительные инструменты, которые мне помогут. Например, приложение по организации настроек системы и программ, позволяющее одним нажатием применить все настройки, или хотя бы в полу-автоматическом режиме следить за прогрессом. Приложение по поиску дубликатов файлов, а также по объединению их атрибутов (например, самая старая дата модификации идентичной копии файла, очевидно, верная, и если на другом файле по ошибке стоит более новая дата, скажем, какое-то неосторожное копирование её сбросило, то нужно восстановить). Приложение, которое поможет наводить порядок в коллекции сканированных документов (переворачивать, уменьшать, организовывать - так, чтобы был очень удобный интерфейс, намного лучше обычного "проводника").

Для таких задач нужно писать код. Мне это вроде как надо под Windows, соответственно легче всего это было бы писать на C#. Но хочется убить больше зайцев одним махом, и в домашних задачах практиковать ту среду разработки, которую я использую на работе, а это Scala и JVM. Заодно была идея освоить Swing в качестве GUI framework, мне это пригодится в будущем и для других задач. Операции с файлами, вроде вытаскивания разных служебных атрибутов (дата модификации, создания, доступа), права доступа, имена, содержащие неанглийские буквы и т.п., всё это требует нативного доступа к системным функциям. Библиотечные Scala-вские, предоставляемые через JVM, будут недостаточны. Они кросс-платформенные, поэтому содержат только те функции, которые есть во всех операционках, и это более ограниченный набор, чем то, что есть конкретно в Windows. Кроме того, системные функции мне нужны для того, чтобы сделать ускорение, которое я хотел - чтобы "сервер" с JVM постоянно висел в памяти, готовый к работе, а приложения-клиенты обращались к нему. Это позволит избежать 1 секунды задержки при запуске приложений на Scala, будут запускаться моментально. Такой обмен можно сделать кроссплатформенным образом, на TCP/IP, но это требует открытия портов - некрасиво и небезопасно, а также может вызвать конфликты с другими приложениями в будущем, если они выбрали те же номера для портов. Поэтому лучше использовать другие средства, например, Named Pipes и security ACLs в файловой системе. А это, опять же, нативный доступ к системным функциям, стандартными средствами не предусмотренный.

Запуск функции MessageBox напрямую из системной DLL-ки USER32 - это пример вызова системной функции из среды Scala/JVM. Раз это получилось, вызывать любую другую функцию тоже будет просто. Т.е. разобраться, как вызывать хоть какую-нибудь функцию - это значительный шаг, продвигающий меня к другим целям.
From:li111
Date:January 26th, 2018 10:13 pm (UTC)
(Link)
Вот теперь все предельно ясно !
:)
From:natpy
Date:January 27th, 2018 02:45 am (UTC)
(Link)
Мне кажется большинство из этого можно было бы сделать скриптами на Тотал Коммандер
From:morfizm
Date:January 27th, 2018 02:59 am (UTC)
(Link)
Может быть, но...
1. Мне нужно не большинство, а всё перечисленное плюс ещё много.
2. Брать зависимость от availability приложения в будущем это рискованнее, чем брать зависимость от популярного языка программирования и сопутствующих библиотек.
3. Осваивать новый скриптовый язык, специфичный для конкретного приложения - минимальной полезности опыт, и никуда не переносимый. Мой вариант имеет synergies и с работой, и с другими хобби-проектами.
From:metaller
Date:January 26th, 2018 11:01 pm (UTC)
(Link)
А ведь мог бы посмотреть вебинар по торговле опциями/фьючерсами ;)
From:morfizm
Date:January 27th, 2018 08:57 pm (UTC)
(Link)
Мог бы и станцевать, и записать на ютуб :) Я многое мог бы. Приходится выбирать из множества вкусных вещей самую вкусную.
From:unstablebear
Date:January 27th, 2018 07:32 am (UTC)
(Link)
Круто! Я почти год скалы не касаюсь, она жива еще, куда ветер дует?
From:morfizm
Date:January 27th, 2018 08:56 pm (UTC)
(Link)
Ветер дует в сторону необходимости владеть функциональными языками. Я вижу, что группы, в которых люди не хотят в них разбираться, это группы, которые держат пока есть работа в legacy системах, но если кто-то из них уходит, новых туда не берут. Т.е. не увольняют агрессивно, но освобождаются от людей через attrition.

Я успел вовремя запрыгнуть на этот паровоз, и он таки стремительно отходит :)
Следующий паровоз, на который надо успеть запрыгнуть это machine learning. Там ситуация похожая: через какое-то время, люди, которые в нём не разбираются, будут не нужны. По крайней мере, они будут не нужны на передовой линии, в самых "вкусных" проектах.
From:unstablebear
Date:January 28th, 2018 03:13 pm (UTC)
(Link)
Судя по наблюдениям, тут(в Швеции) спрос на функциональщину не очень высокий, в прошлой конторе тимлид пушил переход на Scala, а так в большинстве контор прилипли к Java и не собираются ничего менять, грустно. В текущей конторе бакенд на Java, но я постепенно склоняю народ попробовать что-нибудь менее кондовое. У Scala тут репутация умирающего вследствие своей сложности языка, поэтому я пока агитирую за Kotlin, еще вот подсадил коллег на vavr - библиотека для Java идейно вдохновленная Scala, в ней запилили более композабельные стримы, Option'ы и т.п. Фронтендщик у нас пока один, сам себе хозяин, последний месяц все смотрит на ReasonML, похоже перейдет на него таки, пока консервативных коллег не прибавилось :)

Если все программисты переквалифицируются на ML(что подразумевает знание мат. статистики, специфичных фреймворков), кто ж будет все остальное программировать? Даже во вкусных проектах есть всякие CRUDы на микросервисах и вот это все. Может я "вкусные" проекты по другому понимаю.

Я кстати больше про будущее Scala спрашивал, с вашей точки зрения, не загибается ли?

From:morfizm
Date:January 28th, 2018 04:10 pm (UTC)
(Link)
Про будущее Scala - с моей точки зрения, наоборот, продвигается вперёд. Но у меня данные о популярности той или иной технологии идут с задержкой в 1-2 года, потому что собираются они в основном через знакомых, которые меняют работу, а это, хоть и часто происходит, но ненастолько, чтобы в real time track'ать популярность.

Насчёт Scala vs Java - мне кажется, противопоставлять Scala и Java это неправильно. Scala основана на JVM, всё, что в ней есть - это syntax sugar. Современная Java быстра и не настолько отвратительна по многословности, как это было раньше, и в ней (плюс библиотеки) множество инструментов, делающих её сравнимой с чтобы красиво реализовывать функциональный подход, и все вытакающие из него полезности.

Мне лично Scala больше нравится, но это потому что я прошёл через те два месяца, которые я ничего не понимал :) Т.е. я признаю, что learning curve is kinda steep. Впрочем, если по-человечески писать на Java или даже на C++11/14, то тоже будет learning curve.

Противопоставлять надо "старую школу" - императивный подход, мутабельные состояния, single-threaded applications, и parallel distributed stream processing, futures, немутабельные объекты, отсутствие side effects, математическую доказуемость корректности, etc. Здесь очевидно, что старая школа отмирает. Вернее: для неё всегда найдётся место. Она удобна в скриптах и прототипах. Она нужна в OS development, drivers/tools, games, financial industry/trading (а также куча "динозавровых" индустрий вроде healthcare, government, defense, space, etc). Она нужна там, где куча legacy софта, который будет жить ещё десятки лет. Вроде внутренних систем неайтишных компаний. Но это всё области, которые либо сужаются, либо растут, но гораздо медленее, чем растут cloud services, cloud storage/services/applications, social, и новые стартапы, делающие разный cutting edge. В общем, там где много денег :)


> Если все программисты переквалифицируются на ML(что подразумевает знание мат. статистики, специфичных фреймворков), кто ж будет все остальное программировать?

Вот именно. Есть такая мысль, что в какой-то момент всего остального не будет. Или будет, но в очень узких областях, случайному программисту на хлеб с маслом не хватит. Ему нужно будет либо в ML, либо в эти узкие области, либо водителем Убера. На мой взгляд, мне лично бояться этого последнего варианта не надо, на мой век (сколько там той карьеры осталось) хватит legacy stuff'а (впрочем, мне нравится бежать впереди, даже если рационально это не является необходимостью), но вот молодым, которые только начинают, им этого бояться уже надо.
From:unstablebear
Date:January 31st, 2018 08:07 pm (UTC)
(Link)
То что Scala это только синтаксический сахар для Java это перебор, хоть и несильный :)

> Противопоставлять надо "старую школу" - императивный подход, мутабельные состояния, single-threaded applications, и parallel distributed stream processing, futures, немутабельные объекты, отсутствие side effects, математическую доказуемость корректности, etc.

Про смену парадигм согласен. Немутабельность, доказуемость корректности - разве Java тут не продувает Scala? В Scala система типов сильно выразительней, ей можно пользоваться и не быть погребенным под кучей бойлерплейта. Такое мое впечатление.

По поводу светлого будущего когда AI заменит программистов, было бы интересно посмотреть, надеюсь скорость решения социальных проблем будет поспевать за скоростью решения проблем технических.