Всем привет! На связи я, и мое настроение - немного вынести вам мозг, а потом собрать его и разложить по полкам. Поэтому я придумал этот цикл статей, где опытный копипастер расскажет менее опытным компипастерам, как накопипастить внешнюю компоненту для 1С.
Итак, приступим.
1. Языки программирования.
В стародревние времена умные существа придумали компьютер, который программировался нажатием тумблеров, поворачиванием рычагов и прочими мутными способами. Поэтому другие умные существа тут же придумали языки программирования. Началось все, предположу, с таких языков, как ассемблер, который был в сути своей мнемоническим обозначением машинных команд. А слово "мнемонический" у меня, лично, ассоциируется с Джонни Мнемоником - парнем, который, если мне не изменяет память, приторговывал своей памятью.
Но скоро умным существам наскучил и ассемблер, что привело к бурному рассвету языкопридумывания. И вот уже все, кому не лень, кинулись защищать свои докторские, придумывая все новые и новые языки программирования. Потом докторские сменились кандидатскими, потом дипломными, затем курсовыми работами, и вот уже каждый детсадовец придумал себе по языку программирования. Именно поэтому их так много. Именно поэтому бедные входители в ИТ теперь выбирают между "какой язык учить" и "да ну его - буду проституткой РП" (все ж видели эту картинку, да?)
2. Программирование.
Испокон веков программированием (ну сразу после ассемблера, хотя и там не сильно сложнее) были в сути своей три операции:
- Присваивание.
- Условный переход.
- Безусловный переход.
Дальнейшее развитие языков шло по пути переиспользования кода - все эти процедуры/функции и передаваемые им параметры, возвращаемые ими результаты, вся эта богомерзкая рекурсия и богообразное ООП с его классами, методами, наследованием, инкапсуляциями и полиморфизмом...
В итоге все программирование сначала свелось к алгоритмам, которые быстро вошли в разнообразные библиотеки, из которых собрались разнообразные фреймворки, а потом превратилось в унылую копипасту со стековерфлоу Инфостарта.
Ну и для того, чтобы было что копипастить и переиспользовать, я и пишу очередную статью.
3. Язык С++
Ну вот, дошли до какой-то сути.
Итак, язык С++ - это такой непростой для современного копипастера язык, т.к. в нем помимо копипасты самого кода, нужно еще скопипастить команды, с помощью которых этот код соберется и превратится в нашем случае в работающую внешнюю компоненту. И если собрать простую программу достаточно просто, то если программа вдруг использует какие-то библиотеки (а она использует, поверьте), сборка некоторым образом усложняется.
3.1. Программа
Ну давайте перейдем к примерчикам. Начнем с хеллоу-ворлда:
#include <iostream>
int main(int argc, char **argv)
{
std::cout << "Hello. world!" << std::endl;
}
Блин, даже строчку с описанием функции я скопипастил, ибо не помню, что там argc, а что там argv. Зато все остальное воспроизвел по памяти, так что есть еще порох в пороховницах!
3.2. Компиляция программы
Чтобы наша программа заработала, надо ее откомпилировать. Компиляция превращает файл с текстом программы в программу. Притом компиляция состоит из двух эпизодов: создание объектного файла (даже не спрашивайте, что это - я с этим последний раз в 2000-м сталкивался и уже забыл, что мне не мешает писать на С++ внешние компоненты), а во второй части марлезонского балета объектный файл линкуется с библиотеками, которые автор программы решил использовать (нередко даже не подозревая, что он их использует).
Итак, давайте скомпилим. И да, давайте скомпилим и для винды, которой я пользуюсь на работе, и для линукса, в котором пишу эту статью.
#WINDOWS
cl.exe heloworld.cpp
#LINUX
g++ heloworld.cpp
Ну вот, никакой возни в гиперпространстве, никаких ключей компиляции - ничего! А на выходе у меня файл "a.out", запуск которого показывает, что я не зря ем котлеты на обед!
$ cat a.cpp
#include <iostream>
int main(int argc, char **argv)
{
std::cout << "Hello. world!" << std::endl;
}
$ g++ a.cpp
$ ./a.out
Hello. world!
Начало положено: программа написана, скомпилирована и запущена! Пользы никакой, но чувство удовлетворения прям вот прет из организма!
4. Инфраструктура
Ну вот я такой взял и скомпилировал программу у себя на компьютере! Кто молодец? Я молодец! Но если вы попробуете это все на своем компьютере провернуть, то, боюсь, у вас это может не выйти. Почему? Потому, что для создания программы нужны, как бы это банально ни звучало, свои программы. Список программ условно такой:
- Компилятор.
- Библиотеки.
Если вы используете православный линукс, то нужно установить пакет с компилятором и библиотеками с помощью пакетного менеджера. В убунту этот пакет называется build-essential и ставится как-то так:
sudo apt install build-essential
Этого уже достаточно и для компиляции нашего примера, и для сборки внешней компоненты.
Если же у вас богомерзкая венда, то вам придется установить гигабайтищи визуал студио. Если кто-то знает, как поставить минимальный набор для сборки в винде из командной строки - расскажите в комментах. И да, не предлагайте WSL - внешнюю компоненту для винды можно собрать только на виндовом компиляторе ль мелкомягких. По крайней мере я нигде не нашел, как это можно сделать по другому. Но если вы это знаете - напишите в комментариях, буду крайне признателен.
Также в винде для упрощения жизни мелкомягкие придумали несколько батушников, которые запускают среду для сборки, в которой уже прописаны все эти переменные окружения, которые позволяют просто и со вкусом написать то самое "cl helloworld.cpp". Они там где-то зарыты в меню пуск и называются типа "визуал студио девлопмент тулз комманд промпт бла-бла-бла". И там их несколько - для 32-битной сборки, для 64-битной, для кросс-платформы и для чего-то еще - развлекайтесь, ну или просто запустите MS Visual Studio и пишите прям там, но тогда такой лаконичности не выйдет. Да и вообще надо бы понимать, как там оно внутри крутится без всех этих CMake.
Я надеюсь, вы сами разберетесь, как там и что в винде установить? Если нет, то поставьте себе vscode, а там плагин для С++, из ридми которого можно провалиться на сайт мелкомягких и найти крайне запутанный мануал (впрочем, как и любой другой мануал от мелкомягких, написанный китайским студентом в перерывах между парами за столовскую котлету).
5. Внешняя компонента
Итак, дошли до внешних компонент. И тут есть больше, чем одна возможность.
5.1. А какие могут быть варианты?
В действительности, на просторах гитхаба раскидано несколько вариантов внешних компонент, которые отличаются от того, что предоставляет 1С в своем архиве с описанием технологии этих внешних компонент создания. Я не буду касаться вариантов СОМ - этому посвящены просто горы различных трудов: диссертаций, курсовых, детсадовских поделок, ... Давайте посмотрим быстрым взором на то, что гуглится не отходя от кассы.
Итак, вариант номер раз - это мануал от самой 1С с какими-то примерами. Общую информацию можно посмотреть тут, а полный архив доступен на ИТС.
Вариант номер два - это шаблон от infactum, на который ссылаются не только лишь все. Но там есть проблема с именами свойств на русском в linux x64 - они у меня состоят из одной буквы в отладчике и не могут быть изменены. При том в винде все ок и на x64, и на x32.
Вариант номер три - шаблон от kandr который тоже ссылается на шаблон номер два, который ссылается на... Мне, кстати, этот шаблон понравился больше, т.к. в нем, в отличие от infactum, нет проблем в linux x64 с именами свойств.
5.2. Сборка.
Скачать пример - полбеды, нужно его умудриться собрать.
Итак, для linux это делается так (для варианта от infacrum):
g++ dllmain.cpp exports.cpp Component.cpp SampleAddIn.cpp -I../include -shared -o myvklib.so -O2 -std=c++17 -fPIC -static-libstdc++
Запускать сборку этой командой следует из каталога src. Без ключа -fPIC не соберется. -О2 сильно уменьшит размер компоненты, ключ -static-libstdc++ статически линкует стандартную библиотеку, делая компоненту переносимой между разными линуксами (но это не точно).
Для того, чтобы собрать это чудо в винде, нужно такое заклинание:
cl dllmain.cpp exports.cpp Component.cpp SampleAddIn.cpp /I../include /DWINDOWS /D_WINDOWS /EHsc /MT /LD /LINK /DEF:addin.def
Ну и не забываем, что писать это заклинение надо из командной строки, которая уже содержит все те переменные окружения и находится в глубинах меню "Пуск" под именем "что-то там вижуал студио девлопмент тулз комманд промпт ...".
На сегодня все, в скором времени продолжим и попробуем заставить шаблон делать что-нибудь полезное. Кстати, накидывайте идей полезного в комментах.