Это сайт — моя персональная записная книжка. Интересна мне, по большей части, история, своя жизнь и немного программирование.

Первые эксперименты с C#

Поучился обращаться к динамическим библиотекам «Мака» (dylib) из Си-шарпа. Не очень удобно, надо сказать. Вот во что превратилась моя функция macSleepAwake из сишной программы MacGreener:

using System; 
using System.Runtime.InteropServices;
using MonoMac;
using MonoMac.CoreFoundation;
using MonoMac.ObjCRuntime;

namespace MacGreenerFragment
{
    class SleepAwake
    {
        [DllImport ("IOKit", CharSet = CharSet.Ansi)]
        static extern int IORegistryEntryFromPath (IntPtr masterPort, string path);

        [DllImport ("IOKit")]
        static extern void IOObjectRelease (int @object);

        [DllImport ("IOKit")]
        static extern void IORegistryEntrySetCFProperty(int entry, IntPtr propertyName, IntPtr property);

        static void macSleepAwake(bool sleep)
        {
            var handle   = Dlfcn.dlopen (Constants.CoreFoundationLibrary, 0);
            IntPtr True  = Dlfcn.GetIntPtr (handle, "kCFBooleanTrue");
            IntPtr False = Dlfcn.GetIntPtr (handle, "kCFBooleanFalse");

            int r = IORegistryEntryFromPath(IntPtr.Zero, "IOService:/IOResources/IODisplayWrangler");
            if (r != 0) {
                IORegistryEntrySetCFProperty(r, ((CFString)"IORequestIdle").Handle, sleep ? True : False);
                IOObjectRelease(r);
            }
        }
    }
}

На Си это 11 строк.

8 комментариев
Константин 2013

На Си это 11 строк.

Тут 12.

Евгений Степанищев (bolknote.ru) 2013

Комментарий для Константин:

Тут 33.

Константин 2013

33

В сишном варианте не посчитаны хидеры, точнее инклюды, да и подключение либы за скобками.

Сами функции примерно равны.

Если делать по-честному, то надо листинг с хидерами, загрузкой dll, поиском функций и т. п.

А так подсчёт нечестный. Тут всё подсчитано, в сишном варианте только тело функции.

Евгений Степанищев (bolknote.ru) 2013

Комментарий для Константин:

В сишном варианте не посчитаны хидеры, точнее инклюды, да и подключение либы за скобками.

Подсчитаны. Иклюд там, нужный для этого участка кода, — один, я его посчитал. Давайте добавим сюда и подключение либы, это плюс одна строка (стало 12 строк). Сами функции равны, говорите? Ну да, правда сама функция в Си# на три строки длиннее.

Но кому это интересно? Я на весь код смотрю, функция без этого кода не работает, она без него бесполезна.

Константин 2013

Я немного про другое, тут мы видим явное подключение либы — в коде, а в сишном варианте оно «за скобками».

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

В итоге в реале разброс не такой значительный.

Если бы шарповая обёртка использовалась было примерно бы как у СИ.

Евгений Степанищев (bolknote.ru) 2013

Комментарий для Константин:

Я немного про другое, тут мы видим явное подключение либы — в коде, а в сишном варианте оно «за скобками».
Вместо прототипов в сишном просто инклюд, в шарповом прототипы.
В сишном подключение либы подключение конкретно либы тоже где то прописано. Не в подсчитанных строках, но есть. И это тоже руками задаётся.

Я понимаю о чём вы. Но в сишном варианте подключение библиотеки это +1 строка.

Посмотрите как легко подключается сишная библиотека в Гоу: https://github.com/bolknote/go-gd/blob/master/gd.go (строки с 4 по 11), потом все типы и функции из Си доступны в псевдомодуле «C» (C.gdImageCreate, например), между тем Гоу от Си отличается сильнее, чем Си# от Си.

Константин 2013

В Си, +1 строка, только потому, что хидер уже написан.

Гоу от Си отличается сильнее, чем Си# от Си

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

С другой стороны Шарп разрабатывался под виртуальную машину, так что не сильно удивительно, что подружить его с полностью unsafe Си трудно.

Евгений Степанищев (bolknote.ru) 2013

Комментарий для Константин:

В Си, +1 строка, только потому, что хидер уже написан.

Согласен, но вы объясняете причину, но я её и так знаю. Следствие же из неё — код на Си сильно короче, каким бы не был повод. Когда я говорю «код на Си», я имею ввиду мой код на Си, конечно же, а не совокупный код вообще.

Си-шарп мне тоже немного помогает своим модулем MonoMac, в котором, например, есть тип CFString, который не так уж и прост. CFBoolean только почему-то отсутствует, хотя в проекте на ГитХабе я его вижу, видимо, он в продуктив ещё не вышел. Без MonoMac код был бы в несколько раз больше.

С другой стороны Шарп разрабатывался под виртуальную машину, так что не сильно удивительно, что подружить его с полностью unsafe Си трудно.

Раздражает, что это «трудно» не в смысле «неподъёмная задача», а скорее «рутинная, долгая».