LINUX.ORG.RU

Microsoft выпустила официальную Rust библиотеку для Windows API

 , , , ,


1

4

Библиотека оформлена в виде Rust crate под MIT License, который можно использовать вот так:

[dependencies]
windows = "0.2.1"

[build-dependencies]
windows = "0.2.1"

После этого в скрипте сборки build.rs можно сгенерировать те модули, которые нужны для вашего приложения:

fn main() {
    windows::build!(
        windows::data::xml::dom::*
        windows::win32::system_services::{CreateEventW, SetEvent, WaitForSingleObject}
        windows::win32::windows_programming::CloseHandle
    );
}

Документация о доступных модулях опубликована на docs.rs.

Пример кода:

mod bindings {
    ::windows::include_bindings!();
}

use bindings::{
    windows::data::xml::dom::*,
    windows::win32::system_services::{CreateEventW, SetEvent, WaitForSingleObject},
    windows::win32::windows_programming::CloseHandle,
};

fn main() -> windows::Result<()> {
    let doc = XmlDocument::new()?;
    doc.load_xml("<html>hello world</html>")?;

    let root = doc.document_element()?;
    assert!(root.node_name()? == "html");
    assert!(root.inner_text()? == "hello world");

    unsafe {
        let event = CreateEventW(
            std::ptr::null_mut(),
            true.into(),
            false.into(),
            std::ptr::null(),
        );

        SetEvent(event).ok()?;
        WaitForSingleObject(event, 0);
        CloseHandle(event).ok()?;
    }

    Ok(())
}

Для некоторых вызовов функций используется unsafe, так как эти функции предоставляются как они есть, не адаптируя их к конвенциями Rust. По такому же принципу устроен crate libc, который служит базовым crate для доступа к libc и используется как основа для пострения библиотек с безопасным интерфейсом.

Проект создан в рамках Win32 Metadata Project, который призван облегчить создание API для разных языков программирования. Вторая библиотека, которая была создана на основе Metadata Project на первое фазе проекта - C#/Win32. Также Microsoft анонсировала начало работы над версией для С++, которая использует современный стиль языка.

>>> Github

★★★★★

Проверено: Shaman007 ()
Последнее исправление: atsym (всего исправлений: 11)

А зачем эта новость здесь?

gns ★★★★★
()
Ответ на: комментарий от nemec784

Довольно забавно, потому что вот тут они же префиксы для мемберов использовать не рекомендуют. (хотя если порыться, можно найти документы где наоборот - рекомендуют, или предлагают выбирать самим - MSDN в своем стиле)

Но видимо привычки просто так не победить.

Midael ★★★★★
()
Последнее исправление: Midael (всего исправлений: 2)
Ответ на: комментарий от hummer

Нет, конечно. Писать функции для конвертации одних в другие. Их всё равно придётся писать, но так не забудешь использовать.

Miguel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Маленькая проблема: Шимони изобрёл свою нотацию за несколько лет до появления C++ и за много лет до его стандартизации.

Miguel ★★★★★
()

Разве ансейв во все поля не убивает на корню базовую идею раст? Я думал его писали как такой си, в котором утечки и прочие переполнение невозможны. А так получился ещё один си. Или исправят? Или я неправ?

pihter ★★★★★
()
Ответ на: комментарий от pihter

Ты не прав. В C у тебя вообще весь код unsafe, здесь – лишь небольшая часть. То есть, обосраться ты конечно всё равно можешь, но уже с некоторым трудом.

hateyoufeel ★★★★★
()
Ответ на: комментарий от invy

Какой смысл велосипедить что-то на нативном апи

нативное апи предоставляет больше возможностей и быстрее?

rust же про скорость, это не Python какой-нибудь или прочий тормозной шлак

fsb4000 ★★★★★
()
Ответ на: комментарий от Hungarian-Deniska

зачем нужен libc.so, разве gcc генерирует не совместимый Linux код?

Или зачем нужен gtk4, gtk3, gtk2, gtk1. Разве gcc генерирует не совместимый gtk код?

(В redist кроме стандартной библиотеки С++ также находится MFC, и в разных redist разные версии)

fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 1)
Ответ на: комментарий от pornandme

Интересно, а можно таскать свою libc.so вместе со своей програмой?

В Linux?

Можно, только нужно ещё ld-linux.so.2 таскать. Но вполне можно.

fsb4000 ★★★★★
()
Ответ на: комментарий от slackwarrior

майкрософт забьет на rust и/или купит их с потрохами

вроде где-то читал, что они уже наняли почти всех уволенных из мозиллы растоманов.

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

Lrrr ★★★★★
()

Хотят писать на Rust, пусть пишут, главное - чтоб новые версии Винды в Qemu запускалась. Wine - не все приложения качественно запускает, ReactOS тоже.

b0r1s
()
Ответ на: комментарий от Hungarian-Deniska

А кстати зачем эти редистры вообще нужны? Разве Студия не генерит совместимый Win32 код?

Там аналоги libc, libc++. Вроде как Rust завязан на libc, поэтому нужно ставить.

Legioner ★★★★★
()
Ответ на: комментарий от fsb4000

зачем нужен libc.so, разве gcc генерирует не совместимый Linux код?

Я примерно так и подумал. То есть, эти либы в системе есть, но они старые. А редистр это все равно, что libstdc++6 обновить. Например, штатный пониманиет только до C++11, а обновы дают поддержку C++14/17. Я правильно мыслю? То есть, чтобы гарантированно запускалось на дефолтных виндах, надо собирать старой Студией (2010)? А какой C стандарт умеют изкоробочные семерка и икспишка?

Hungarian-Deniska
()
Ответ на: комментарий от pihter

Разве ансейв во все поля не убивает на корню базовую идею раст?

Частично убивает. Поэтому поверх этого API по-хорошему нужно писать свою безопасную прослойку, которую в дальнейшем и использовать.

Я думал его писали как такой си, в котором утечки и прочие переполнение невозможны.

От утечек Rust не защищает. И нет, это не С, это совсем другой язык, гораздо более высокого уровня.

Или исправят? Или я неправ?

Что тут можно исправить? Если API небезопасно, значит оно небезопасно. Единственное, что тут можно сделать, это попробовать написать безопасную прослойку с другим API.

Legioner ★★★★★
()
Ответ на: комментарий от Hungarian-Deniska

Использование виндовой libc это неподдерживаемый юз-кейс. Хотя технически это можно делать, все настоятельно рекомендуют этого не делать. Она там лежит для компонентов винды, а не для тебя. В общем забудь. Или компилируй статически, или таскай DLL с собой, как положено.

Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 2)
Ответ на: комментарий от pornandme

В юниксах в libc лежит и ядерный интерфейс, всякие write(2) и т.д. С ним могут быть проблемы. Конкретно в линуксе интерфейс ядра стабильный и так делать можно. В других ОС, например macOS сисколлы не считаются стабильными и могут меняться в разных версиях, поэтому твоя программа обязана использовать динамическую линковку с местным libc и вызывать ядерные функции через неё.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

удобный всем

Ставить по 10500 редистров? + то что проги еще тащят с собой на всякий случай и пихают во все щели.

Я как-то в Total Uninstall наблюдал, одна прога прямо в system32 раскатила.

Hungarian-Deniska
()
Ответ на: комментарий от fsb4000

Если интересными возможностями glibc особо не пользоваться, то можно очень просто собрать статически с http://musl.libc.org/

MOPKOBKA ★★★★
()
Ответ на: комментарий от Hungarian-Deniska

Там много трабл может возникнуть, glibc для такого не предназначается.

MOPKOBKA ★★★★
()
Ответ на: комментарий от Legioner

Использование виндовой libc это неподдерживаемый юз-кейс. Хотя технически это можно делать, все настоятельно рекомендуют этого не делать

Почему тогда не все проги требуют редистры и запускаются из коробки?

Hungarian-Deniska
()
Ответ на: комментарий от Hungarian-Deniska

Я не знаю. Не проблема установить все(или почти все) редисты в систему и забить на это.

У меня установлено 12 штук: https://i.imgur.com/I5DXeMf.png

Вообще да, какие-то библиотеки устанавливаются вместе с Windows. В Windows 8 помоему был предустановлен Visual C++ 2012 redis, но проще приложить установщик нужного рантайма, или просто написать какой нужен…

fsb4000 ★★★★★
()
Ответ на: комментарий от Hungarian-Deniska

Mingw требует всякие такие библиотеки:

libgcc_s_dw2-1.dll libstdc++-6.dll и прочие чтобы находились в папке с бинарником

fsb4000 ★★★★★
()
Ответ на: комментарий от Hungarian-Deniska

Я заметил, Wine их уже содержит вплоть до 2019. Хотя может там не все функции реализованы. Тот случай, когда виндузятники вынуждены ставить гору библиотек, а в Wine все работает из коробки. Читаешь их инструкции на сайтах и ухмыльняешься.

Hungarian-Deniska
()
Ответ на: комментарий от fsb4000

В Windows 8 помоему был предустановлен Visual C++ 2012

Ну логично. То, что было на момент выхода встраивают. Такая же ситуация с .Net.
2005-2007 семерка уже содержит.

Hungarian-Deniska
()
Ответ на: комментарий от Hungarian-Deniska

А MingW как делает? Ведь его бинарники не требуют редистров. Вшивает в файл наверное.

Не знаю, никогда не изучал его. Но, думаю, там своя libc. Судя по этому вопросу там точно так же нужно таскать DLL.

Ставить по 10500 редистров? + то что проги еще тащят с собой на всякий случай и пихают во все щели.

Ну и что.

Я как-то в Total Uninstall наблюдал, одна прога прямо в system32 раскатила.

Видимо какая-то совсем старая программа. Современные вроде в C:\Windows\WinSxS должны ставить.

Почему тогда не все проги требуют редистры и запускаются из коробки?

Есть три основных способа. Первый способ это скомпилировать программу статически. Тогда libc и всё остальное будет в EXE-файле, ничего больше не нужно. Второй способ это положить несколько десятков DLL-ок рядом с EXE-файлом. Тоже ничего не нужно устанавливать. И третий способ это при инсталляции своей программы установить vcredist в системные каталоги. Преимущество третьего способа в экономии места, если несколько программ зависят от одной версии vcredist. Лично я бы использовал второй способ.

Чисто теоретически можно ещё писать программу, используя исключительно WinAPI, без libc. Тогда зависимостей никаких не будет и EXE-файл будет крошечным. Но это довольно сложно делать.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

Видимо какая-то совсем старая программа

Да, вот эта https://www.videohelp.com/software/Bitrate-Viewer-2

Чисто теоретически можно ещё писать программу, используя исключительно WinAPI, без libc. Тогда зависимостей никаких не будет и EXE-файл будет крошечным. Но это довольно сложно делать

Ясно, получается первый способ совсем не Ъ, как я думал.

Hungarian-Deniska
()
Ответ на: комментарий от Legioner

например macOS сисколлы не считаются стабильными и могут меняться в разных версиях, поэтому твоя программа обязана использовать динамическую линковку с местным libc

А почему про линусы говорят, что при аналогичном подходе програма запустится далеко не везде? Выходит в линуксах API (ABI) у libc менее стабильное?

pornandme
()
Ответ на: комментарий от pornandme

А почему про линусы говорят, что при аналогичном подходе програма запустится далеко не везде?

Не знаю, почему говорят. Должна запуститься.

Выходит в линуксах API (ABI) у libc менее стабильное?

Если у тебя старая программа не запускается на новом линуксе, значит где-то баг. Или в программе, или в линуксе. В целом в любой достаточно сложной программе есть вероятность багов, которые не проявлялись на старых системах, но могут проявиться на новых, поэтому в реальности, конечно, могут быть нюансы. Но в теории совместимость есть и старые программы должны запускаться на новых ядрах и libc.

Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 2)
Ответ на: комментарий от Miguel

В то время уже был Ada, где эту проблему порешали.

beck ★★★★
()
Ответ на: комментарий от fsb4000

Не обязательно, линкуйся статически к musl и динамический линковщик не нужен

balsoft ★★
()
Ответ на: комментарий от pornandme

Нет.

например macOS сисколлы не считаются стабильными и могут меняться в разных версиях, поэтому твоя программа обязана использовать динамическую линковку с местным libc

А почему про линусы говорят, что при аналогичном подходе програма запустится далеко не везде? Выходит в линуксах API (ABI) у libc менее стабильное?

Это не так. Программа запустится и отработает. Просто, в разных версиях разделяемых библиотек могут быть отличия в вызовах. Для именно и чисто разделяемых библиотек (той же glibc) существует правило, что если там определён некий вызов функции в версии библиотеки N, то если мы хотим создать более продвинутую версию в версии библиотеки N+1, то мы должны оставить старую версию вызова, либо пометив её как deprecated и создав новую версию вызова, либо оставив как есть и так же создав новую версию вызова. Это делает API, not ABI(!) системы весьма стабильным. Об этом Ульрих Дреппер писал (где-то здесь https://software.intel.com/sites/default/files/m/a/1/e/dsohowto.pdf было). Кроме того, очевидным образом экономится память и ресурсы за счёт того, что либа одна, а используется многими приложениями.

Если хочется вот прямо чумовой стабильности и хотя бы каких гарантий, как например, это делается в системах с повышенными требованиями к безопасности, то используется статическая линковка и что-нибудь из аналогов glibc – uClibc, musl, newlib. Размер их кода сравнительно мал, размер кода приложений увеличивается (но не скорость, т.к. самая быстрая реализация это всё таки, glibc), но не так сильно, как если бы мы прилинковали статически саму glibc, подсунуть какую-то «левую» реализацию здесь тоже не получится (и атаковать таким образом систему). Так что, такой вариант тоже имеет право на существование, тут уже вообще и сразу пофиг что за API в системе используется, тут всё и сразу есть в самом приложении. Из известных мне решений, например, такой подход используется в генту-подобном дистрибутиве, заточенном на цели безопасности – pentoo. Ну или в случае gentoo, которая собрана будет именно таким образом (в gentoo можно и так и этак, там вообще можно как хочешь).

Но в любом случае проблем с API быть не должно, если API грамотно спроектирован и используется.

Moisha_Liberman ★★
()
Ответ на: комментарий от Hungarian-Deniska

Немного не так.

А MingW как делает? Ведь его бинарники не требуют редистров. Вшивает в файл наверное.

Если я не ошибаюсь, то в MingW происходит трансляция вызовов Linux API в Windows API. «Вшивает», да и то относительно, это Cygwin. Почему для него и нужно со своим win-приложением передавать ещё cygwin.dll. С приложением, собранным в MingW этого делать ненужно, т.к. получается нативное виндовое приложение.

Moisha_Liberman ★★
()

api, microsoft, opensource, rust, windows

Отличное сочетание тэгов. Теперь понятно, откуда ноги rustут.

Вопрос к знатокам: раст легче или быстрее чем c/c++?

acroobat
()
Ответ на: комментарий от WatchCat

Ага.

Это примерно как на сишечку с плюсами наезжать за платформо-ориентированные либы.

Я вообще считаю что платформоориентированность в случае с С и С++ это то, на чём стоим. Хочется кроссплатформенности – сразу в Java. Там она истинная, а не мнимая.

/* И да, кроссплатформенность это зло. В моём понимании. Потому что ни два, ни полтора получается на выходе. Вроде, работает, но как-то не так, как хотелось бы. */

Moisha_Liberman ★★
()
Ответ на: комментарий от Legioner

Но в теории совместимость есть и старые программы должны запускаться на новых ядрах и libc

Поэтому браузеры собирают в CentOS 6. Теперь уже в 7.

Hungarian-Deniska
()
Ответ на: Ага. от Moisha_Liberman

Кроссплатформенность это объективная реальность, а не зло. У нас нету «айн фольк, айн рейх, айн фюрер». Особенно это касается всяческих серверных направлений и встраиваемых систем.

WatchCat ★★★★★
()
Ответ на: комментарий от acroobat

Бггг... =)))

Вопрос к знатокам: раст легче или быстрее чем c/c++?

А это уже не вопрос, а вброс. И хороший такой вброс. =))) Сейчас прилетит толпа, забывшая открыть для себя и прочесть MISRA, SEI CERT C coding standard, MITRE CWE and CERT Secure Coding Standards, не умеющая пользоваться splint и cppcheck и расскажут нам (вот уже в который раз!) про то, как же небезопасен С и С++ (по их мнению, ага).

Ну а про скорость это будет отдельная песня. Правда, окружающий их мир ничего не знает об их «просвящённом» мнении и по этой причине как писал критические системы на С и С++, так и пишет. =)))

Кстати, хорошо что от Царя огородили этот тред. Во-время. Одни и те же вопли читать уже изрядно поднадаело. Спасибо.

Moisha_Liberman ★★
()
Ответ на: комментарий от kmeaw

Могли бы функции с суффиксом W затащить без него, а к старым версиям добавить суффикс A.

Затем, что у них там очередной фатальный недостаток. Решили воскресить A-API, добавив туда UTF-8. :)

atrus ★★★★★
()
Ответ на: комментарий от WatchCat

Меня лично не волнуют...

проблемы виндарей, если честно. У меня сервера это то, что называется Hardened Gentoo, хотя, там по сравнению с более ранними реализациями Hardened поистаскался малость, но в общем и целом для целей безопасности пойдёт. Реже – Astra. А встраиваемки это, как правило что-то Linux-based (как yocto, так и buildroot, aka OpenWRT), либо вообще просто и сразу Linux (та же gentoo на ARM/Aarch64/MIPS). Про десктоп/ноут даже сразу не говорю – gentoo, реже ubuntu или astra и те в виртуалках.

Запустил как-то по дури на Raspberry Pi 2 windows-приблуду (можно жи!) уровня hello_world, малость прифигел от старта приблуды примерно в 1 мунуту, 40 секунд. Грязно выругался и с тех пор забыл об этом.

Возможно что у кого-то стек разработки шире, но я как-то вот так для себя решил проблемы с кроссплатформенностью. Забыл о ней. =)

Moisha_Liberman ★★
()
Ответ на: Меня лично не волнуют... от Moisha_Liberman

Ну это частности. А так, как пример, был у ребят неплохой гис-софт, но под винду. А потом оказалось возможность получить вкусный госзаказ. Вот только заказчик захотел ещё в качестве таргет-платформ Linux и QNX. Причём если была бы у них базовой платформой Linux, то ситуация не сильно бы изменилась.

Можно конечно гордо отказаться, но кто ж себе такой гордый буратина?

WatchCat ★★★★★
()
Последнее исправление: WatchCat (всего исправлений: 1)
Ответ на: Нет. от Moisha_Liberman

Спасибо. Не ожидал столь подробного ответа )

используется статическая линковка и что-нибудь из аналогов glibc – uClibc, musl, newlib

На фоне гиганских бинарников, что генерит раст, наверное и glibc статически прилинкованный не заметен

pornandme
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.