├── .gitignore
├── CMakeLists.txt
├── Compile.bat
├── Example.xml
├── Example
├── Forms
│ ├── Form.xml
│ ├── Form
│ │ └── Ext
│ │ │ ├── Form.xml
│ │ │ └── Form
│ │ │ └── Module.bsl
│ ├── Test.xml
│ └── Test
│ │ └── Ext
│ │ ├── Form.xml
│ │ └── Form
│ │ └── Module.bsl
├── Templates
│ └── NativeAddIn.xml
└── filename
├── LICENSE
├── README.md
├── appveyor.ps1
├── appveyor.yml
├── build.sh
├── include
├── .gitattributes
├── AddInDefBase.h
├── ComponentBase.h
├── IMemoryManager.h
├── com.h
└── types.h
├── manifest.ps1
├── src
├── AddInNative.cpp
├── AddInNative.def
├── AddInNative.h
├── AddInNative.rc
├── TestComponent.cpp
├── TestComponent.h
└── stdafx.h
├── take-screenshot.ps1
├── template.xml
└── version.h
/.gitignore:
--------------------------------------------------------------------------------
1 | /database
2 | /build64Win
3 | /build32Win
4 | /build64Lin
5 | /build32Lin
6 | /build64
7 | /build32
8 | /build
9 | /tools
10 | /bin
11 | /.vc
12 | /.vs
13 | /.vscode
14 | /Autotest.log
15 | /Example/fileversion
16 | /Example/Templates/NativeAddIn/Ext/Template.bin
17 | /Decompile.bat
18 | manifest.xml
19 | *.epf
20 | *.o
21 | *.d
22 | *.so
23 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.10)
2 | project(NativeAddIn)
3 | set(TARGET NativeAddIn)
4 |
5 | add_library(${TARGET} SHARED
6 | src/AddInNative.cpp
7 | src/AddInNative.def
8 | src/AddInNative.h
9 | src/AddInNative.rc
10 | src/TestComponent.cpp
11 | src/TestComponent.h
12 | src/stdafx.h)
13 |
14 | target_compile_definitions(${TARGET} PRIVATE UNICODE _UNICODE)
15 | target_include_directories(${TARGET} PRIVATE include)
16 | set (LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)
17 | set (EXECUTABLE_OUTPUT_PATH ${LIBRARY_OUTPUT_PATH})
18 | set (CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH})
19 |
20 | if (UNIX)
21 | if (APPLE)
22 | set(MySuffix1 "Mac")
23 | else(APPLE)
24 | set(MySuffix1 "Lin")
25 | endif(APPLE)
26 | if (TARGET_PLATFORM_32)
27 | set(MySuffix2 "32")
28 | else()
29 | set(MySuffix2 "64")
30 | endif()
31 | else(UNIX)
32 | if (NOT MSVC)
33 | message(FATAL_ERROR "Must be compiled with MSVC on Windows")
34 | endif(NOT MSVC)
35 | set(MyPrefix "lib")
36 | set(MySuffix1 "Win")
37 | endif(UNIX)
38 |
39 | set_target_properties( ${PROJECT_NAME} PROPERTIES
40 | OUTPUT_NAME ${MyPrefix}${PROJECT_NAME}${MySuffix1}${MySuffix2}
41 | POSITION_INDEPENDENT_CODE ON
42 | CXX_STANDARD_REQUIRED ON
43 | CXX_STANDARD 17
44 | )
45 |
46 | if (UNIX)
47 | if (TARGET_PLATFORM_32)
48 | set(CMAKE_C_FLAGS "-m32 ${CMAKE_C_FLAGS}")
49 | set(CMAKE_CXX_FLAGS "-m32 ${CMAKE_CXX_FLAGS}")
50 | else(TARGET_PLATFORM_32)
51 | set(CMAKE_C_FLAGS "-m64 ${CMAKE_C_FLAGS}")
52 | set(CMAKE_CXX_FLAGS "-m64 ${CMAKE_CXX_FLAGS}")
53 | endif ()
54 | target_link_libraries(${PROJECT_NAME} -static-libstdc++)
55 | else(UNIX)
56 | add_definitions(/MT)
57 | set(CMAKE_SUPPRESS_REGENERATION 1)
58 | set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "" FORCE)
59 | target_compile_definitions(${TARGET} PRIVATE _WINDOWS
60 | _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING)
61 | target_compile_options(${TARGET} PRIVATE /utf-8)
62 | endif(UNIX)
63 |
--------------------------------------------------------------------------------
/Compile.bat:
--------------------------------------------------------------------------------
1 | mkdir build32Win
2 | cd build32Win
3 | cmake .. -A Win32 -DMySuffix2=32
4 | cmake --build . --config Release
5 | cd ..
6 |
7 | mkdir build64Win
8 | cd build64Win
9 | cmake .. -A x64 -DMySuffix2=64
10 | cmake --build . --config Release
11 | cd ..
12 |
--------------------------------------------------------------------------------
/Example.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | c3831ec8-d8d5-4f93-8a22-f9bfae07327f
7 | b6622ba9-c532-479a-b95b-39920ff960dc
8 |
9 |
10 | 383922ed-c955-4407-b2bd-96592d7e4ae9
11 | d45b137a-41d0-463e-b0d8-6712991436b7
12 |
13 |
14 |
15 | Example
16 |
17 |
18 | ru
19 | Example
20 |
21 |
22 |
23 | ExternalDataProcessor.Example.Form.Form
24 |
25 |
26 |
27 |
28 |
29 | NativeAddIn
30 |
31 |
32 |
--------------------------------------------------------------------------------
/Example/Forms/Form.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
22 |
--------------------------------------------------------------------------------
/Example/Forms/Form/Ext/Form.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Example/Forms/Form/Ext/Form/Module.bsl:
--------------------------------------------------------------------------------
1 | &НаСервере
2 | Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
3 |
4 |
5 | ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
6 | МакетКомпоненты = ОбработкаОбъект.ПолучитьМакет("NativeAddIn");
7 | МетоположениеКомпоненты = ПоместитьВоВременноеХранилище(МакетКомпоненты, УникальныйИдентификатор);
8 |
9 | ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
10 | ФайлОбработки = Новый Файл(ОбработкаОбъект.ИспользуемоеИмяФайла);
11 | ТекущийКаталог = ФайлОбработки.Путь;
12 |
13 | БольшоеЧисло = 3147483647;
14 |
15 | КонецПроцедуры
16 |
17 | &НаКлиенте
18 | Процедура ТестКомпоненты(Команда)
19 |
20 | УстановитьВнешнююКомпоненту(МетоположениеКомпоненты);
21 | ПодключитьВнешнююКомпоненту(МетоположениеКомпоненты, "TestAddin", ТипВнешнейКомпоненты.Native);
22 | ВнешняяКомпонента = Новый("AddIn.TestAddin.SimpleAlias");
23 |
24 | Сообщить("Версия: " + ВнешняяКомпонента.Версия);
25 |
26 | ВнешняяКомпонента.TEXT = "Свойство: ";
27 | Сообщить(ВнешняяКомпонента.ТексТ);
28 |
29 | ВнешняяКомпонента.УстановитьТЕКСТ("Функция: ");
30 | Сообщить(ВнешняяКомпонента.ПолучитьТЕКСТ());
31 |
32 | ВнешняяКомпонента.УстановитьТЕКСТ();
33 | Сообщить(ВнешняяКомпонента.ПолучитьТЕКСТ());
34 |
35 | ВнешняяКомпонента.Число = БольшоеЧисло;
36 | ТипЗначения = ВнешняяКомпонента.Число;
37 |
38 | КонецПроцедуры
39 |
40 | &НаКлиенте
41 | Процедура Автотест(Команда)
42 |
43 | Массив = СтрРазделить(ИмяФормы, ".");
44 | Массив[Массив.Количество() - 1] = "Test";
45 | НовоеИмя = СтрСоединить(Массив, ".");
46 | ОткрытьФорму(НовоеИмя);
47 |
48 | КонецПроцедуры
49 |
50 |
--------------------------------------------------------------------------------
/Example/Forms/Test.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
22 |
--------------------------------------------------------------------------------
/Example/Forms/Test/Ext/Form.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Example/Forms/Test/Ext/Form/Module.bsl:
--------------------------------------------------------------------------------
1 | &НаСервере
2 | Перем ВК, Лог;
3 |
4 | &НаКлиенте
5 | Процедура ПриОткрытии(Отказ)
6 |
7 | Для каждого ЭлементСписка из СписокУзлов Цикл
8 | Элементы.Результаты.Развернуть(ЭлементСписка.Значение, Истина);
9 | КонецЦикла;
10 | СписокУзлов.Очистить();
11 |
12 | // ПодключитьОбработчикОжидания("ЗавершитьРаботу", 1, Истина);
13 |
14 | КонецПроцедуры
15 |
16 | &НаКлиенте
17 | Процедура ЗавершитьРаботу()
18 |
19 | ЗавершитьРаботуСистемы(Ложь);
20 |
21 | КонецПроцедуры
22 |
23 | &НаСервере
24 | Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
25 |
26 | ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
27 | ФайлОбработки = Новый Файл(ОбработкаОбъект.ИспользуемоеИмяФайла);
28 | ТекущийКаталог = ФайлОбработки.Путь;
29 |
30 | ИдКомпоненты = "_" + StrReplace(New UUID, "-", "");
31 | МакетКомпоненты = ОбработкаОбъект.ПолучитьМакет("NativeAddIn");
32 | АдресКомпоненты = ПоместитьВоВременноеХранилище(МакетКомпоненты, УникальныйИдентификатор);
33 | ПодключитьВнешнююКомпоненту(АдресКомпоненты, ИдКомпоненты, ТипВнешнейКомпоненты.Native);
34 | ВК = Новый("AddIn." + ИдКомпоненты + ".SimpleAlias");
35 |
36 | ВыполнитьТесты();
37 |
38 | КонецПроцедуры
39 |
40 | &НаСервере
41 | Функция ТестВычислитьXML(ИмяКласса, ИмяТеста, Выражение)
42 |
43 | //Лог = Новый ЗаписьXML;
44 | //Лог.ОткрытьФайл(ТекущийКаталог + "autotest.log");
45 | //Лог.ЗаписатьНачалоЭлемента("testsuites");
46 |
47 | //Лог.ЗаписатьНачалоЭлемента("testsuite");
48 | //Лог.ЗаписатьАтрибут("name", "Свойства");
49 | //Лог.ЗаписатьАтрибут("timestamp", timestamp());
50 | //Лог.ЗаписатьКонецЭлемента();
51 |
52 | //Лог.ЗаписатьКонецЭлемента();
53 | //Лог.Закрыть();
54 |
55 |
56 | Лог.ЗаписатьНачалоЭлемента("testsuite");
57 | Лог.ЗаписатьАтрибут("classname", ИмяКласса);
58 | Лог.ЗаписатьАтрибут("name", ИмяТеста);
59 | Попытка
60 | Значение = Вычислить(Выражение);
61 | Лог.ЗаписатьНачалоЭлемента("system-out");
62 | Лог.ЗаписатьТекст(Значение);
63 | Лог.ЗаписатьКонецЭлемента();
64 | Исключение
65 | Значение = Неопределено;
66 | Информация = ИнформацияОбОшибке();
67 | Лог.ЗаписатьНачалоЭлемента("error");
68 | Лог.ЗаписатьАтрибут("message", КраткоеПредставлениеОшибки(Информация));
69 | Лог.ЗаписатьКонецЭлемента();
70 |
71 | Лог.ЗаписатьНачалоЭлемента("system-err");
72 | Лог.ЗаписатьТекст(ПодробноеПредставлениеОшибки(Информация));
73 | Лог.ЗаписатьКонецЭлемента();
74 | КонецПопытки;
75 | Лог.ЗаписатьКонецЭлемента();
76 |
77 | Возврат Значение;
78 |
79 | КонецФункции
80 |
81 | &НаСервере
82 | Процедура ТестВыполнитьXML(ИмяКласса, ИмяТеста, Выражение)
83 |
84 | Лог.ЗаписатьНачалоЭлемента("testsuite");
85 | Лог.ЗаписатьАтрибут("classname", ИмяКласса);
86 | Лог.ЗаписатьАтрибут("name", ИмяТеста);
87 | Попытка
88 | Выполнить(Выражение);
89 | Исключение
90 | Информация = ИнформацияОбОшибке();
91 | Лог.ЗаписатьНачалоЭлемента("error");
92 | Лог.ЗаписатьАтрибут("message", КраткоеПредставлениеОшибки(Информация));
93 | Лог.ЗаписатьКонецЭлемента();
94 |
95 | Лог.ЗаписатьНачалоЭлемента("system-err");
96 | Лог.ЗаписатьТекст(ПодробноеПредставлениеОшибки(Информация));
97 | Лог.ЗаписатьКонецЭлемента();
98 | КонецПопытки;
99 | Лог.ЗаписатьКонецЭлемента();
100 |
101 | КонецПроцедуры
102 |
103 | &НаСервере
104 | Функция timestamp()
105 |
106 | Возврат Формат(ТекущаяУниверсальнаяДата(), "ДФ=гггг-ММ-ддTчч:мм:сс");
107 |
108 | КонецФункции
109 |
110 | &НаСервере
111 | Функция ПрочитатьСтрокуJSON(ТекстJSON)
112 |
113 | Если ПустаяСтрока(ТекстJSON) Тогда
114 | Возврат Неопределено;
115 | КонецЕсли;
116 |
117 | ПоляДаты = Новый Массив;
118 | ПоляДаты.Добавить("CreationDate");
119 | ПоляДаты.Добавить("date");
120 |
121 | ЧтениеJSON = Новый ЧтениеJSON();
122 | ЧтениеJSON.УстановитьСтроку(ТекстJSON);
123 | Возврат ПрочитатьJSON(ЧтениеJSON, , ПоляДаты);
124 |
125 | КонецФункции
126 |
127 | &НаСервере
128 | Функция ДобавитьГруппуТестов(Наименование)
129 |
130 | Стр = Результаты.ПолучитьЭлементы().Добавить();
131 | СписокУзлов.Добавить(Стр.ПолучитьИдентификатор());
132 | Стр.Наименование = Наименование;
133 | Возврат Стр;
134 |
135 | КонецФункции
136 |
137 | &НаСервере
138 | Функция ТестВычислить(Группа, ИмяТеста, Выражение)
139 |
140 | Стр = Группа.ПолучитьЭлементы().Добавить();
141 | Стр.Наименование = ИмяТеста;
142 | Стр.Выражение = Выражение;
143 | Попытка
144 | Значение = Вычислить(Выражение);
145 | Стр.Значение = Значение;
146 | Исключение
147 | Значение = Неопределено;
148 | Информация = ИнформацияОбОшибке();
149 | Стр.ТекстОшибки = КраткоеПредставлениеОшибки(Информация);
150 | Стр.Подробности = ПодробноеПредставлениеОшибки(Информация);
151 | Стр.Ошибка = Истина;
152 | Группа.Ошибка = Истина;
153 | КонецПопытки;
154 |
155 | Возврат Значение;
156 |
157 | КонецФункции
158 |
159 | &НаСервере
160 | Процедура ТестВыполнить(Группа, ИмяТеста, Выражение)
161 |
162 | Стр = Группа.ПолучитьЭлементы().Добавить();
163 | Стр.Наименование = ИмяТеста;
164 | Стр.Выражение = Выражение;
165 | Попытка
166 | Выполнить(Выражение);
167 | Исключение
168 | Значение = Неопределено;
169 | Информация = ИнформацияОбОшибке();
170 | Стр.ТекстОшибки = КраткоеПредставлениеОшибки(Информация);
171 | Стр.Подробности = ПодробноеПредставлениеОшибки(Информация);
172 | Стр.Ошибка = Истина;
173 | Группа.Ошибка = Истина;
174 | КонецПопытки;
175 |
176 | КонецПроцедуры
177 |
178 | &НаСервере
179 | Процедура ВыполнитьТесты()
180 |
181 | Группа = ДобавитьГруппуТестов("Свойства компоненты");
182 | ТестВычислить(Группа, "Получить:Version", "ВК.Version");
183 | ТестВычислить(Группа, "Получить:Версия", "ВК.Версия");
184 | ТестВычислить(Группа, "Получить:ВЕРСИЯ", "ВК.ВЕРСИЯ");
185 | ТестВычислить(Группа, "Получить:Текст", "ВК.Текст");
186 | ТестВычислить(Группа, "Получить:Проверка", "ВК.Проверка");
187 | ТестВыполнить(Группа, "Установить:Версия", "ВК.Текст = ""Тест""");
188 | ТестВыполнить(Группа, "Установить:Проверка", "ВК.Проверка = ""Тест""");
189 |
190 | Группа = ДобавитьГруппуТестов("Методы компоненты");
191 | ТестВыполнить(Группа, "УстановитьТекст()", "ВК.УстановитьТекст(""Тест"")");
192 | ТестВычислить(Группа, "ПолучитьТекст()", "ВК.ПолучитьТекст()");
193 |
194 | КонецПроцедуры
--------------------------------------------------------------------------------
/Example/Templates/NativeAddIn.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NativeAddIn
6 |
7 |
8 | ru
9 | Native add in
10 |
11 |
12 |
13 | BinaryData
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Example/filename:
--------------------------------------------------------------------------------
1 | Example.epf
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Kandrashin Denis
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AddinTemplate - шаблон внешней компоненты 1С
2 |
3 | Для облегчения работы с шаблоном весь программный код, который не должен
4 | изменяться разработчиком при реализации собственных библиотек внешних
5 | компонент, собран в файлах **AddInNative.cpp** и **AddInNative.h**.
6 |
7 | Автор предлагает собственную оригинальную реализацию, которая хотя и лишена
8 | изящества шаблона [Infactum](https://github.com/Infactum/addin-template),
9 | тоже позволяет регистрировать компоненту под несколькими именами,
10 | использует лямбда-выражения для регистрации компоненты в библиотеке, при определении
11 | свойств и методов. При обращении к свойствам и методам регистр игнорируется.
12 |
13 | Отказ от использования шаблонов для определения процедур и функций в предлагаемой
14 | реализации компоненты накладывает существенные ограничения на формат лямбда выражений
15 | в методах **AddProperty**, **AddProcedure** и **AddFunction**, поскольку требует
16 | обязательного использования агрументов типа **VH** (короткий синоним **VariantHelper**).
17 | Это позволяет легко решить задачу возврата в 1С измененных значений параметров.
18 | Для возврата результата функции используется член базового класса **result**.
19 |
20 | Пример кода для регистрации компоненты в библиотеке:
21 | ```Cpp
22 | std::vector TestComponent::names = {
23 | AddComponent(u"AddInNative", []() { return new TestComponent; }),
24 | AddComponent(u"SimpleAlias", []() { return new TestComponent; }),
25 | };
26 |
27 | TestComponent::TestComponent()
28 | {
29 | AddProperty(u"Text", u"Текст",
30 | [&](VH prop) { prop = this->getTestString(); },
31 | [&](VH prop) { this->setTestString(prop); }
32 | );
33 |
34 | AddFunction(u"GetText", u"ПолучитьТекст",
35 | [&]() { this->result = this->getTestString(); }
36 | );
37 |
38 | AddProcedure(u"SetText", u"УстановитьТекст",
39 | [&](VH param) { this->setTestString(param); },
40 | { {0, u"Default"} }
41 | );
42 | }
43 |
44 | ```
45 |
--------------------------------------------------------------------------------
/appveyor.ps1:
--------------------------------------------------------------------------------
1 | $account = "lintest"
2 | $project = "AddinTemplate"
3 | $name = "NativeAddIn"
4 |
5 | #https://ci.appveyor.com/api-keys
6 | $token = $env:API_TOKEN
7 | $url1c = $env:URL_1CV8T
8 | $path = $env:APPVEYOR_BUILD_FOLDER
9 | $version = $env:APPVEYOR_BUILD_VERSION
10 | $postfix = '_' + $version -replace '\.', '_'
11 | Update-AppveyorBuild -Version "$version"
12 | Write-Output "Version: $version"
13 |
14 | $apiUrl = 'https://ci.appveyor.com/api'
15 | $headers = @{
16 | "Authorization" = "Bearer $token"
17 | "Content-type" = "application/json"
18 | }
19 |
20 | $project = Invoke-RestMethod -Method Get -Uri "$apiUrl/projects/$account/$project/build/$version" -Headers $headers
21 |
22 | $jobId = $project.build.jobs[0].jobId
23 | $artifacts = Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts" -Headers $headers
24 | $artifactFileName = $artifacts[0].fileName
25 |
26 | Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/$artifactFileName" `
27 | -OutFile "$path\Linux.zip" -Headers @{ "Authorization" = "Bearer $token" }
28 |
29 | Expand-Archive -Force -Path "$path\Linux.zip" -DestinationPath $path
30 |
31 | Rename-Item "$path\lib${name}Win32.dll" "${name}Win32$postfix.dll"
32 | Rename-Item "$path\lib${name}Win64.dll" "${name}Win64$postfix.dll"
33 | Rename-Item "$path\lib${name}Lin32.so" "${name}Lin32$postfix.so"
34 | Rename-Item "$path\lib${name}Lin64.so" "${name}Lin64$postfix.so"
35 |
36 | $compress = @{
37 | Path = "$path\$name*.dll", "$path\$name*.so", "$path\manifest.xml"
38 | DestinationPath = "$path\AddIn.zip"
39 | }
40 | Compress-Archive @compress
41 |
42 | New-Item -ItemType Directory -Force -Path "$path\Example\Templates\$name\" | Out-Null
43 | New-Item -ItemType Directory -Force -Path "$path\Example\Templates\$name\Ext\" | Out-Null
44 | Copy-Item -Path "$path\AddIn.zip" -Destination "$path\Example\Templates\$name\Ext\Template.bin"
45 |
46 | $dist1c = "$path\1cv8.zip"
47 | if (!(Test-Path $dist1c)) {
48 | Write-Host "Download 1cv8.zip ..."
49 | Invoke-WebRequest -Uri $url1c -OutFile $dist1c
50 | }
51 |
52 | Write-Host "Expand archive 1cv8.zip ..."
53 | Expand-Archive -Force -Path $dist1c -DestinationPath $path
54 | Set-Content "$path\bin\conf\conf.cfg" "DisableUnsafeActionProtection=.*;"
55 |
56 | & "bin\1cv8t.exe" DESIGNER /F "$path\Data" /LoadExternalDataProcessorOrReportFromFiles "Example.xml" "$name.epf" /Out"Example.log"
57 |
58 | Write-Host "Process autotest..."
59 | #Start-Process "bin\1cv8ct.exe" -ArgumentList "/F $path\Autobase" -Wait
60 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | version: 0.3.4.{build}
2 | configuration: Release
3 | platform: x64
4 |
5 | branches:
6 | only:
7 | - develop
8 |
9 | skip_branch_with_pr: true
10 |
11 | environment:
12 | global:
13 | URL_1CV8T:
14 | secure: z47uplaqZaQ0ZkroXy0GP00nv6ACPwovtb+EjfPgpS0IlWM6VQd+8apwLfqT9ndX
15 | API_TOKEN:
16 | secure: 85XpT8I1bxRTZaiIA+co0b5GS05J2VOn7PzunkYlL40=
17 |
18 | matrix:
19 | - APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu1804
20 | job_name: Linux
21 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
22 | job_depends_on: Linux
23 | job_name: Windows
24 |
25 | install:
26 | - sh: sudo dpkg --add-architecture i386
27 | - sh: sudo apt -qq update
28 | - sh: sudo apt -qq -y install uuid-dev
29 | - sh: sudo apt -qq -y install gcc-multilib g++-multilib
30 |
31 | init:
32 | - cmd: cmake --version
33 | - cmd: msbuild /version
34 | - cmd: echo.
35 |
36 | build_script:
37 | - sh: echo "#define VERSION_FULL " ${APPVEYOR_BUILD_VERSION} > "version.h"
38 | - cmd: Powershell.exe -File manifest.ps1 -Project NativeAddIn -Version %APPVEYOR_BUILD_VERSION%
39 |
40 | - mkdir build32
41 | - cd build32
42 | - sh: cmake -D CMAKE_BUILD_TYPE:STRING=Release -D TARGET_PLATFORM_32:BOOL=ON --build ..
43 | - cmd: cmake .. -A Win32 -DMySuffix2=32
44 | - cmake --build . --config Release
45 | - cd ..
46 |
47 | - mkdir build64
48 | - cd build64
49 | - sh: cmake -D CMAKE_BUILD_TYPE:STRING=Release -D TARGET_PLATFORM_32:BOOL=OFF --build ..
50 | - cmd: cmake .. -A x64 -DMySuffix2=64
51 | - cmake --build . --config Release
52 | - cd ..
53 |
54 | - sh: cp bin/libNativeAddInLin??.so .
55 | - sh: 7z a NativeAddIn.zip libNativeAddInLin??.so
56 | - cmd: copy bin\Release\libNativeAddInWin??.dll .
57 | - cmd: Powershell.exe -File appveyor.ps1
58 |
59 | for:
60 | - matrix:
61 | only:
62 | - job_name: Linux
63 | artifacts:
64 | - path: NativeAddIn.zip
65 | name: NativeAddIn
66 |
67 | - matrix:
68 | only:
69 | - job_name: Windows
70 |
71 | cache: 1cv8.zip
72 |
73 | artifacts:
74 | - path: AddIn.zip
75 | name: AddIn
76 |
77 | - path: NativeAddIn.epf
78 | name: NativeAddIn
79 |
80 | - path: example.log
81 | name: example log
82 |
83 | deploy:
84 | - provider: GitHub
85 | auth_token:
86 | secure: v7P89NQ2I5+WGNNdhpFrZEt6OCTPf8A8VSC5rttZMXh3DJ2fTChNEjZ1Wvm3kfBt
87 | repository: lintest/AddinTemplate
88 | artifact: AddIn.zip, NativeAddIn.epf
89 | draft: true
90 | prerelease: true
91 | force_update: true
92 | on:
93 | branch: develop
94 | APPVEYOR_REPO_TAG: true
95 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | mkdir build32Lin
4 | cd build32Lin
5 | cmake -D CMAKE_BUILD_TYPE:STRING=Release -D TARGET_PLATFORM_32:BOOL=ON --build ..
6 | cmake --build .
7 | cd ..
8 |
9 | mkdir build64Lin
10 | cd build64Lin
11 | cmake -D CMAKE_BUILD_TYPE:STRING=Release -D TARGET_PLATFORM_32:BOOL=OFF --build ..
12 | cmake --build .
13 | cd ..
14 |
--------------------------------------------------------------------------------
/include/.gitattributes:
--------------------------------------------------------------------------------
1 | * -text
2 |
--------------------------------------------------------------------------------
/include/AddInDefBase.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Warning!!!
3 | * DO NOT ALTER THIS FILE!
4 | */
5 |
6 | #ifndef __ADAPTER_DEF_H__
7 | #define __ADAPTER_DEF_H__
8 | #include "types.h"
9 |
10 | struct IInterface
11 | {
12 | };
13 |
14 |
15 | enum Interfaces
16 | {
17 | eIMsgBox = 0,
18 | eIPlatformInfo,
19 |
20 | #if defined(__ANDROID__)
21 |
22 | eIAndroidComponentHelper,
23 |
24 | #endif
25 |
26 | };
27 |
28 | ////////////////////////////////////////////////////////////////////////////////
29 | /**
30 | * This class serves as representation of a platform for external
31 | * components External components use it to communicate with a platform.
32 | *
33 | */
34 | /// Base interface for object components.
35 | class IAddInDefBase
36 | {
37 | public:
38 | virtual ~IAddInDefBase() {}
39 | /// Adds the error message
40 | /**
41 | * @param wcode - error code
42 | * @param source - source of error
43 | * @param descr - description of error
44 | * @param scode - error code (HRESULT)
45 | * @return the result of
46 | */
47 | virtual bool ADDIN_API AddError(unsigned short wcode, const WCHAR_T* source,
48 | const WCHAR_T* descr, long scode) = 0;
49 |
50 | /// Reads a property value
51 | /**
52 | * @param wszPropName -property name
53 | * @param pVal - value being returned
54 | * @param pErrCode - error code (if any error occured)
55 | * @param errDescriptor - error description (if any error occured)
56 | * @return the result of read.
57 | */
58 | virtual bool ADDIN_API Read(WCHAR_T* wszPropName,
59 | tVariant* pVal,
60 | long *pErrCode,
61 | WCHAR_T** errDescriptor) = 0;
62 | /// Writes a property value
63 | /**
64 | * @param wszPropName - property name
65 | * @param pVar - new property value
66 | * @return the result of write.
67 | */
68 | virtual bool ADDIN_API Write(WCHAR_T* wszPropName,
69 | tVariant *pVar) = 0;
70 |
71 | ///Registers profile components
72 | /**
73 | * @param wszProfileName - profile name
74 | * @return the result of
75 | */
76 | virtual bool ADDIN_API RegisterProfileAs(WCHAR_T* wszProfileName) = 0;
77 |
78 | /// Changes the depth of event buffer
79 | /**
80 | * @param lDepth - new depth of event buffer
81 | * @return the result of
82 | */
83 | virtual bool ADDIN_API SetEventBufferDepth(long lDepth) = 0;
84 | /// Returns the depth of event buffer
85 | /**
86 | * @return the depth of event buffer
87 | */
88 | virtual long ADDIN_API GetEventBufferDepth() = 0;
89 | /// Registers external event
90 | /**
91 | * @param wszSource - source of event
92 | * @param wszMessage - event message
93 | * @param wszData - message parameters
94 | * @return the result of
95 | */
96 | virtual bool ADDIN_API ExternalEvent(WCHAR_T* wszSource,
97 | WCHAR_T* wszMessage,
98 | WCHAR_T* wszData) = 0;
99 | /// Clears event buffer
100 | /**
101 | */
102 | virtual void ADDIN_API CleanEventBuffer() = 0;
103 |
104 | /// Sets status line contents
105 | /**
106 | * @param wszStatusLine - new status line contents
107 | * @return the result of
108 | */
109 | virtual bool ADDIN_API SetStatusLine(WCHAR_T* wszStatusLine) = 0;
110 | /// Resets the status line contents
111 | /**
112 | * @return the result of
113 | */
114 | virtual void ADDIN_API ResetStatusLine() = 0;
115 | };
116 |
117 | class IAddInDefBaseEx :
118 | public IAddInDefBase
119 | {
120 | public:
121 | virtual ~IAddInDefBaseEx() {}
122 |
123 | virtual IInterface* ADDIN_API GetInterface(Interfaces iface) = 0;
124 | };
125 |
126 | struct IMsgBox :
127 | public IInterface
128 | {
129 | virtual bool ADDIN_API Confirm(const WCHAR_T* queryText, tVariant* retVal) = 0;
130 |
131 | virtual bool ADDIN_API Alert(const WCHAR_T* text) = 0;
132 | };
133 |
134 | struct IPlatformInfo :
135 | public IInterface
136 | {
137 | enum AppType
138 | {
139 | eAppUnknown = -1,
140 | eAppThinClient = 0,
141 | eAppThickClient,
142 | eAppWebClient,
143 | eAppServer,
144 | eAppExtConn,
145 | eAppMobileClient,
146 | eAppMobileServer,
147 | };
148 |
149 | struct AppInfo
150 | {
151 | const WCHAR_T* AppVersion;
152 | const WCHAR_T* UserAgentInformation;
153 | AppType Application;
154 | };
155 |
156 | virtual const AppInfo* ADDIN_API GetPlatformInfo() = 0;
157 | };
158 |
159 | #endif //__ADAPTER_DEF_H__
160 |
--------------------------------------------------------------------------------
/include/ComponentBase.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Warning!!!
3 | * DO NOT ALTER THIS FILE!
4 | */
5 |
6 |
7 | #ifndef __COMPONENT_BASE_H__
8 | #define __COMPONENT_BASE_H__
9 |
10 | #include "types.h"
11 | ////////////////////////////////////////////////////////////////////////////////
12 | /**
13 | * The given interface is intended for initialization and
14 | * uninitialization of component and its adjustments
15 | */
16 | /// Interface of component initialization.
17 | class IInitDoneBase
18 | {
19 | public:
20 | virtual ~IInitDoneBase() {}
21 | /// Initializes component
22 | /**
23 | * @param disp - 1C:Enterpise interface
24 | * @return the result of
25 | */
26 | virtual bool ADDIN_API Init(void* disp) = 0;
27 | /// Sets the memory manager
28 | /*
29 | * @param mem - pointer to memory manager interface.
30 | * @return the result of
31 | */
32 | virtual bool ADDIN_API setMemManager(void* mem) = 0;
33 |
34 | /// Returns component version
35 | /**
36 | * @return - component version (2000 - version 2)
37 | */
38 | virtual long ADDIN_API GetInfo() = 0;
39 |
40 | /// Uninitializes component
41 | /**
42 | * Component here should release all consumed resources.
43 | */
44 | virtual void ADDIN_API Done() = 0;
45 |
46 | };
47 | ///////////////////////////////////////////////////////////////////////////
48 | /**
49 | * The given interface defines methods that are intented to be used by the Platform
50 | */
51 | /// Interface describing extension of language.
52 | class ILanguageExtenderBase
53 | {
54 | public:
55 | virtual ~ILanguageExtenderBase(){}
56 | /// Registers language extension
57 | /**
58 | * @param wsExtensionName - extension name
59 | * @return the result of
60 | */
61 | virtual bool ADDIN_API RegisterExtensionAs(WCHAR_T** wsExtensionName) = 0;
62 |
63 | /// Returns number of component properties
64 | /**
65 | * @return number of properties
66 | */
67 | virtual long ADDIN_API GetNProps() = 0;
68 |
69 | /// Finds property by name
70 | /**
71 | * @param wsPropName - property name
72 | * @return property index or -1, if it is not found
73 | */
74 | virtual long ADDIN_API FindProp(const WCHAR_T* wsPropName) = 0;
75 |
76 | /// Returns property name
77 | /**
78 | * @param lPropNum - property index (starting with 0)
79 | * @param lPropAlias - 0 - international alias,
80 | * 1 - russian alias. (International alias is required)
81 | * @return proeprty name or 0 if it is not found
82 | */
83 | virtual const WCHAR_T* ADDIN_API GetPropName(long lPropNum,
84 | long lPropAlias) = 0;
85 |
86 | /// Returns property value
87 | /**
88 | * @param lPropNum - property index (starting with 0)
89 | * @param pvarPropVal - the pointer to a variable for property value
90 | * @return the result of
91 | */
92 | virtual bool ADDIN_API GetPropVal(const long lPropNum,
93 | tVariant* pvarPropVal) = 0;
94 |
95 | /// Sets the property value
96 | /**
97 | * @param lPropNum - property index (starting with 0)
98 | * @param varPropVal - the pointer to a variable for property value
99 | * @return the result of
100 | */
101 | virtual bool ADDIN_API SetPropVal(const long lPropNum,
102 | tVariant* varPropVal) = 0;
103 |
104 | /// Is property readable?
105 | /**
106 | * @param lPropNum - property index (starting with 0)
107 | * @return true if property is readable
108 | */
109 | virtual bool ADDIN_API IsPropReadable(const long lPropNum) = 0;
110 |
111 | /// Is property writable?
112 | /**
113 | * @param lPropNum - property index (starting with 0)
114 | * @return true if property is writable
115 | */
116 | virtual bool ADDIN_API IsPropWritable(const long lPropNum) = 0;
117 |
118 | /// Returns number of component methods
119 | /**
120 | * @return number of component methods
121 | */
122 | virtual long ADDIN_API GetNMethods() = 0;
123 |
124 | /// Finds a method by name
125 | /**
126 | * @param wsMethodName - method name
127 | * @return - method index
128 | */
129 | virtual long ADDIN_API FindMethod(const WCHAR_T* wsMethodName) = 0;
130 |
131 | /// Returns method name
132 | /**
133 | * @param lMethodNum - method index(starting with 0)
134 | * @param lMethodAlias - 0 - international alias,
135 | * 1 - russian alias. (International alias is required)
136 | * @return method name or 0 if method is not found
137 | */
138 | virtual const WCHAR_T* ADDIN_API GetMethodName(const long lMethodNum,
139 | const long lMethodAlias) = 0;
140 |
141 | /// Returns number of method parameters
142 | /**
143 | * @param lMethodNum - method index (starting with 0)
144 | * @return number of parameters
145 | */
146 | virtual long ADDIN_API GetNParams(const long lMethodNum) = 0;
147 |
148 | /// Returns default value of method parameter
149 | /**
150 | * @param lMethodNum - method index(starting with 0)
151 | * @param lParamNum - parameter index (starting with 0)
152 | * @param pvarParamDefValue - the pointer to a variable for default value
153 | * @return the result of
154 | */
155 | virtual bool ADDIN_API GetParamDefValue(const long lMethodNum,
156 | const long lParamNum,
157 | tVariant *pvarParamDefValue) = 0;
158 |
159 | /// Does the method have a return value?
160 | /**
161 | * @param lMethodNum - method index (starting with 0)
162 | * @return true if the method has a return value
163 | */
164 | virtual bool ADDIN_API HasRetVal(const long lMethodNum) = 0;
165 |
166 | /// Calls the method as a procedure
167 | /**
168 | * @param lMethodNum - method index (starting with 0)
169 | * @param paParams - the pointer to array of method parameters
170 | * @param lSizeArray - the size of array
171 | * @return the result of
172 | */
173 | virtual bool ADDIN_API CallAsProc(const long lMethodNum,
174 | tVariant* paParams,
175 | const long lSizeArray) = 0;
176 |
177 | /// Calls the method as a function
178 | /**
179 | * @param lMethodNum - method index (starting with 0)
180 | * @param pvarRetValue - the pointer to returned value
181 | * @param paParams - the pointer to array of method parameters
182 | * @param lSizeArray - the size of array
183 | * @return the result of
184 | */
185 | virtual bool ADDIN_API CallAsFunc(const long lMethodNum,
186 | tVariant* pvarRetValue,
187 | tVariant* paParams,
188 | const long lSizeArray) = 0;
189 | };
190 | ///////////////////////////////////////////////////////////////////////////
191 | /**
192 | * This interface is used to change component locale
193 | */
194 | /// Base interface for component localization.
195 | class LocaleBase
196 | {
197 | public:
198 | virtual ~LocaleBase(){}
199 | /// Changes component locale
200 | /**
201 | * @param loc - new locale (for Windows - rus_RUS,
202 | * for Linux - ru_RU, etc...)
203 | */
204 | virtual void ADDIN_API SetLocale(const WCHAR_T* loc) = 0;
205 | };
206 |
207 | ///////////////////////////////////////////////////////////////////////////
208 | /**
209 | * The given interface is generalized, for its obligatory inheritance
210 | * in implementing components.
211 | */
212 | /// Base interface describing object as a set of properties and methods.
213 | class IComponentBase :
214 | public IInitDoneBase,
215 | public ILanguageExtenderBase,
216 | public LocaleBase
217 | {
218 | public:
219 | virtual ~IComponentBase(){}
220 | };
221 |
222 | enum AppCapabilities
223 | {
224 | eAppCapabilitiesInvalid = -1,
225 | eAppCapabilities1 = 1,
226 | eAppCapabilitiesLast = eAppCapabilities1,
227 | };
228 |
229 | /// Announcements of exported functions
230 | /**
231 | * These functions should be implemented that component can be loaded and created.
232 | */
233 | extern "C" long GetClassObject(const WCHAR_T*, IComponentBase** pIntf);
234 | extern "C" long DestroyObject(IComponentBase** pIntf);
235 | extern "C" const WCHAR_T* GetClassNames();
236 | extern "C" AppCapabilities SetPlatformCapabilities(const AppCapabilities capabilities);
237 |
238 | typedef long (*GetClassObjectPtr)(const WCHAR_T* wsName, IComponentBase** pIntf);
239 | typedef long (*DestroyObjectPtr)(IComponentBase** pIntf);
240 | typedef const WCHAR_T* (*GetClassNamesPtr)();
241 | typedef AppCapabilities (*SetPlatformCapabilitiesPtr)(const AppCapabilities capabilities);
242 |
243 | #endif //__COMPONENT_BASE_H__
244 |
--------------------------------------------------------------------------------
/include/IMemoryManager.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Warning!!!
3 | * DO NOT ALTER THIS FILE!
4 | */
5 |
6 |
7 | #ifndef __IMEMORY_MANAGER_H__
8 | #define __IMEMORY_MANAGER_H__
9 |
10 | ///////////////////////////////////////////////////////////////////////////////
11 | /**
12 | * The given class allocates and releases memory for a component
13 | */
14 | /// Interface representing memory manager.
15 | class IMemoryManager
16 | {
17 | public:
18 | virtual ~IMemoryManager() {}
19 | /// Allocates memory of specified size
20 | /**
21 | * @param pMemory - the double pointer to variable, that will hold newly
22 | * allocated block of memory of NULL if allocation fails.
23 | * @param ulCountByte - memory size
24 | * @return the result of
25 | */
26 | virtual bool ADDIN_API AllocMemory (void** pMemory, unsigned long ulCountByte) = 0;
27 | /// Releases memory
28 | /**
29 | * @param pMemory - The double pointer to the memory block being released
30 | */
31 | virtual void ADDIN_API FreeMemory (void** pMemory) = 0;
32 | };
33 |
34 | #endif //__IMEMORY_MANAGER_H__
35 |
--------------------------------------------------------------------------------
/include/com.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef __COM_H__
3 | #define __COM_H__
4 |
5 | #if defined(__linux__) || defined(__APPLE__) || defined(__ANDROID__)
6 |
7 | #ifdef __ANDROID__
8 |
9 | typedef struct {
10 | unsigned int Data1;
11 | unsigned short Data2;
12 | unsigned short Data3;
13 | unsigned char Data4[ 8 ];
14 | } uuid_t;
15 |
16 | #else
17 | #include
18 | #endif //__ANDROID__
19 |
20 | #ifndef __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ // iOS
21 | #include
22 | #endif //!__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__
23 |
24 | #pragma GCC system_header
25 |
26 | typedef long HRESULT;
27 |
28 | #ifdef __GNUC__
29 | #define STDMETHODCALLTYPE __attribute__ ((__stdcall__))
30 | #define DECLSPEC_NOTHROW __attribute__ ((nothrow))
31 | #define STDMETHOD(method) virtual DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE method
32 | #else
33 | #define STDMETHODCALLTYPE
34 | #endif
35 |
36 | #define __stdcall STDMETHODCALLTYPE
37 | #define near
38 | #define far
39 | #define CONST const
40 | #define FAR far
41 |
42 | typedef unsigned long DWORD;
43 | #ifndef __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ // iOS
44 | typedef int BOOL;
45 | #elif defined(__LP64__)
46 | typedef bool BOOL;
47 | #else
48 | typedef signed char BOOL;
49 | #endif //!__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__
50 |
51 | typedef void VOID;
52 | typedef short SHORT;
53 | typedef unsigned char BYTE;
54 | typedef unsigned short WORD;
55 | typedef float FLOAT;
56 | typedef FLOAT *PFLOAT;
57 | typedef BOOL near *PBOOL;
58 | typedef BOOL far *LPBOOL;
59 | typedef BYTE near *PBYTE;
60 | typedef BYTE far *LPBYTE;
61 | typedef int near *PINT;
62 | typedef int far *LPINT;
63 | typedef WORD near *PWORD;
64 | typedef WORD far *LPWORD;
65 | typedef long far *LPLONG;
66 | typedef DWORD near *PDWORD;
67 | typedef DWORD far *LPDWORD;
68 | typedef void far *LPVOID;
69 | typedef CONST void far *LPCVOID;
70 | typedef wchar_t *BSTR;
71 | typedef long SCODE;
72 | typedef int INT;
73 | typedef unsigned int UINT;
74 | typedef unsigned int *PUINT;
75 | typedef wchar_t WCHAR;
76 | typedef wchar_t OLECHAR;
77 | typedef wchar_t *LPOLESTR;
78 | typedef const wchar_t *LPCOLESTR;
79 | typedef DWORD LCID;
80 | typedef PDWORD PLCID;
81 | typedef long LONG;
82 | typedef unsigned long ULONG;
83 | typedef long long LONGLONG;
84 | typedef unsigned long long ULONGLONG;
85 | typedef LONG DISPID;
86 | typedef double DOUBLE;
87 | typedef double DATE;
88 | typedef short VARIANT_BOOL;
89 | typedef void *PVOID;
90 | typedef char CHAR;
91 | typedef CONST CHAR *LPCSTR;
92 | typedef unsigned short USHORT;
93 | typedef void *HMODULE;
94 | #define OLESTR(str) L##str
95 |
96 | typedef uuid_t GUID;
97 | typedef uuid_t IID;
98 | typedef uuid_t UUID;
99 | #define REFIID const IID &
100 | #define MAX_PATH 260
101 |
102 | #define IsEqualIID(x,y) uuid_compare((x),(y))
103 | #ifdef __GNUC__
104 | #define LoadLibraryA(x) dlopen((x), RTLD_LAZY)
105 | #define FreeLibrary(x) dlclose((x))
106 | #define GetProcAddress(x, y) dlsym((x), (y))
107 | #endif //__GNUC__
108 |
109 | #define E_FAIL 0x80004005L
110 | #define S_OK 0L
111 | #define S_FALSE 1L
112 | #define E_NOINTERFACE 0x80004002L
113 | #define E_NOTIMPL 0x80004001L
114 | #define E_INVALIDARG 0x80070057L
115 | #define E_UNEXPECTED 0x8000FFFFL
116 | #define E_OUTOFMEMORY 0x8007000EL
117 | #define DISP_E_UNKNOWNNAME 0x80020006L
118 | #define DISPID_UNKNOWN ( -1 )
119 | #define TRUE 1
120 | #define FALSE 0
121 |
122 | typedef long ITypeInfo;
123 |
124 | #if defined (__GNUC__) && !defined (NONAMELESSUNION)
125 | __extension__ /* no named members */
126 | #endif
127 | union tCY {
128 | __extension__ struct
129 | {
130 | unsigned long Lo;
131 | long Hi;
132 | };
133 | long long int64;
134 | };
135 | typedef union tagCY CY;
136 | #define CLSIDFromString(x,y) uuid_parse((x),(unsigned char*)(y))
137 |
138 | #endif //defined(__linux__) || defined(__APPLE__)
139 |
140 | #endif //__COM_H__
141 |
--------------------------------------------------------------------------------
/include/types.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef __CON_TYPES_H__
3 | #define __CON_TYPES_H__
4 |
5 | #if defined(_WINDOWS) || defined(WINAPI_FAMILY)
6 | #include
7 | #endif
8 |
9 | #if defined(WINAPI_FAMILY)
10 | #include
11 | #endif
12 |
13 | #if __GNUC__ >=3
14 | #pragma GCC system_header
15 | #endif
16 |
17 | #include "com.h"
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | #define EXTERN_C extern "C"
24 |
25 | #ifdef __GNUC__
26 | #define _ANONYMOUS_UNION __extension__
27 | #define _ANONYMOUS_STRUCT __extension__
28 | #else
29 | #define _ANONYMOUS_UNION
30 | #define _ANONYMOUS_STRUCT
31 | #endif //__GNUC__
32 |
33 | #ifdef NONAMELESSUNION
34 | #define __VARIANT_NAME_1 u
35 | #define __VARIANT_NAME_2 iface
36 | #define __VARIANT_NAME_3 str
37 | #define __VARIANT_NAME_4 wstr
38 | #else
39 | #define __VARIANT_NAME_1
40 | #define __VARIANT_NAME_2
41 | #define __VARIANT_NAME_3
42 | #define __VARIANT_NAME_4
43 | #endif //NONAMELESSUNION
44 |
45 | #define RESULT_FROM_ERRNO(x) ((long)(x) <= 0 ? ((long)(x)) \
46 | : ((long) (((x) & 0x0000FFFF) | (BASE_ERRNO << 16) | 0x80000000)))
47 |
48 | #define ADDIN_E_NONE 1000
49 | #define ADDIN_E_ORDINARY 1001
50 | #define ADDIN_E_ATTENTION 1002
51 | #define ADDIN_E_IMPORTANT 1003
52 | #define ADDIN_E_VERY_IMPORTANT 1004
53 | #define ADDIN_E_INFO 1005
54 | #define ADDIN_E_FAIL 1006
55 | #define ADDIN_E_MSGBOX_ATTENTION 1007
56 | #define ADDIN_E_MSGBOX_INFO 1008
57 | #define ADDIN_E_MSGBOX_FAIL 1009
58 |
59 | #ifndef ADDIN_API
60 | #ifdef _WINDOWS
61 | #define ADDIN_API __stdcall
62 | #else
63 | //#define ADDIN_API __attribute__ ((__stdcall__))
64 | #define ADDIN_API
65 | #endif //_WINDOWS
66 | #endif //ADDIN_API
67 |
68 | #include
69 |
70 | #ifdef _WINDOWS
71 | #define WCHAR_T wchar_t
72 | #else
73 | #define WCHAR_T uint16_t
74 | #endif //_WINDOWS
75 | typedef unsigned short TYPEVAR;
76 | enum ENUMVAR
77 | {
78 | VTYPE_EMPTY = 0,
79 | VTYPE_NULL,
80 | VTYPE_I2, //int16_t
81 | VTYPE_I4, //int32_t
82 | VTYPE_R4, //float
83 | VTYPE_R8, //double
84 | VTYPE_DATE, //DATE (double)
85 | VTYPE_TM, //struct tm
86 | VTYPE_PSTR, //struct str string
87 | VTYPE_INTERFACE, //struct iface
88 | VTYPE_ERROR, //int32_t errCode
89 | VTYPE_BOOL, //bool
90 | VTYPE_VARIANT, //struct _tVariant *
91 | VTYPE_I1, //int8_t
92 | VTYPE_UI1, //uint8_t
93 | VTYPE_UI2, //uint16_t
94 | VTYPE_UI4, //uint32_t
95 | VTYPE_I8, //int64_t
96 | VTYPE_UI8, //uint64_t
97 | VTYPE_INT, //int Depends on architecture
98 | VTYPE_UINT, //unsigned int Depends on architecture
99 | VTYPE_HRESULT, //long hRes
100 | VTYPE_PWSTR, //struct wstr
101 | VTYPE_BLOB, //means in struct str binary data contain
102 | VTYPE_CLSID, //UUID
103 | VTYPE_STR_BLOB = 0xfff,
104 | VTYPE_VECTOR = 0x1000,
105 | VTYPE_ARRAY = 0x2000,
106 | VTYPE_BYREF = 0x4000, //Only with struct _tVariant *
107 | VTYPE_RESERVED = 0x8000,
108 | VTYPE_ILLEGAL = 0xffff,
109 | VTYPE_ILLEGALMASKED = 0xfff,
110 | VTYPE_TYPEMASK = 0xfff
111 | } ;
112 | #if defined (__GNUC__) && !defined (NONAMELESSUNION)
113 | __extension__ /* no named members */
114 | #endif
115 | struct _tVariant
116 | {
117 | _ANONYMOUS_UNION union
118 | {
119 | int8_t i8Val;
120 | int16_t shortVal;
121 | int32_t lVal;
122 | int intVal;
123 | unsigned int uintVal;
124 | int64_t llVal;
125 | uint8_t ui8Val;
126 | uint16_t ushortVal;
127 | uint32_t ulVal;
128 | uint64_t ullVal;
129 | int32_t errCode;
130 | long hRes;
131 | float fltVal;
132 | double dblVal;
133 | bool bVal;
134 | char chVal;
135 | wchar_t wchVal;
136 | DATE date;
137 | IID IDVal;
138 | struct _tVariant *pvarVal;
139 | struct tm tmVal;
140 | _ANONYMOUS_STRUCT struct
141 | {
142 | void* pInterfaceVal;
143 | IID InterfaceID;
144 | } __VARIANT_NAME_2/*iface*/;
145 | _ANONYMOUS_STRUCT struct
146 | {
147 | char* pstrVal;
148 | uint32_t strLen; //count of bytes
149 | } __VARIANT_NAME_3/*str*/;
150 | _ANONYMOUS_STRUCT struct
151 | {
152 | WCHAR_T* pwstrVal;
153 | uint32_t wstrLen; //count of symbol
154 | } __VARIANT_NAME_4/*wstr*/;
155 | } __VARIANT_NAME_1;
156 | uint32_t cbElements; //Dimension for an one-dimensional array in pvarVal
157 | TYPEVAR vt;
158 | };
159 | typedef struct _tVariant tVariant;
160 | typedef tVariant tVariantArg;
161 |
162 |
163 | #if defined(NONAMELESSUNION)
164 | #define TV_JOIN(X, Y) ((X)->u.Y)
165 | #else
166 | #define TV_JOIN(X, Y) ((X)->Y)
167 | #endif
168 |
169 | #define TV_VT(X) ((X)->vt)
170 | #define TV_ISBYREF(X) (TV_VT(X)&VT_BYREF)
171 | #define TV_ISARRAY(X) (TV_VT(X)&VT_ARRAY)
172 | #define TV_ISVECTOR(X) (TV_VT(X)&VT_VECTOR)
173 | #define TV_NONE(X) TV_I2(X)
174 |
175 | #define TV_UI1(X) TV_JOIN(X, ui8Val)
176 | #define TV_I2(X) TV_JOIN(X, shortVal)
177 | #define TV_I4(X) TV_JOIN(X, lVal)
178 | #define TV_I8(X) TV_JOIN(X, llVal)
179 | #define TV_R4(X) TV_JOIN(X, fltVal)
180 | #define TV_R8(X) TV_JOIN(X, dblVal)
181 | #define TV_I1(X) TV_JOIN(X, i8Val)
182 | #define TV_UI2(X) TV_JOIN(X, ushortVal)
183 | #define TV_UI4(X) TV_JOIN(X, ulVal)
184 | #define TV_UI8(X) TV_JOIN(X, ullVal)
185 | #define TV_INT(X) TV_JOIN(X, intVal)
186 | #define TV_UINT(X) TV_JOIN(X, uintVal)
187 |
188 | #ifdef _WIN64
189 | #define TV_INT_PTR(X) TV_JOIN(X, llVal)
190 | #define TV_UINT_PTR(X) TV_JOIN(X, ullVal)
191 | #else
192 | #define TV_INT_PTR(X) TV_JOIN(X, lVal)
193 | #define TV_UINT_PTR(X) TV_JOIN(X, ulVal)
194 | #endif
195 |
196 |
197 | #define TV_DATE(X) TV_JOIN(X, date)
198 | #define TV_STR(X) TV_JOIN(X, pstrVal)
199 | #define TV_WSTR(X) TV_JOIN(X, pwstrVal)
200 | #define TV_BOOL(X) TV_JOIN(X, bVal)
201 | #define TV_UNKNOWN(X) TV_JOIN(X, pInterfaceVal)
202 | #define TV_VARIANTREF(X) TV_JOIN(X, pvarVal)
203 |
204 | void tVarInit(tVariant* tvar);
205 |
206 | inline
207 | void tVarInit(tVariant* tvar)
208 | {
209 | assert(tvar != NULL);
210 | memset(tvar, 0, sizeof(tVariant));
211 | TV_VT(tvar) = VTYPE_EMPTY;
212 | }
213 | //----------------------------------------------------------------------------//
214 | // static setter functions...
215 |
216 | #define DATA_SET_BEGIN(data_) \
217 | tVarInit(data_);
218 |
219 | #define DATA_SET_END(data_, type_) \
220 | TV_VT(data_) = type_;
221 |
222 |
223 | #define DATA_SET(data_, type_, member_, value_) \
224 | DATA_SET_BEGIN(data_) \
225 | TV_JOIN(data_, member_) = value_; \
226 | DATA_SET_END(data_, type_)
227 |
228 | #define DATA_SET_WITH_CAST(data_, type_, member_, cast_, value_) \
229 | DATA_SET_BEGIN(data_) \
230 | TV_JOIN(data_, member_) = cast_ value_; \
231 | DATA_SET_END(data_, type_)
232 |
233 | #endif //__CON_TYPES_H__
234 |
--------------------------------------------------------------------------------
/manifest.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$project,
3 | [string]$version
4 | )
5 |
6 | $postfix = '_' + $version -replace '\.','_'
7 | $v1,$v2,$v3,$v4 = $version.split('.')
8 | Set-Content 'version.h' "#define VER_FILENAME $project"
9 | Add-Content 'version.h' "#define VERSION_FULL $version"
10 | Add-Content 'version.h' "#define VERSION_MAJOR $v1"
11 | Add-Content 'version.h' "#define VERSION_MINOR $v2"
12 | Add-Content 'version.h' "#define VERSION_REVISION $v3"
13 | Add-Content 'version.h' "#define VERSION_BUILD $v4"
14 |
15 | $encoding = [System.Text.Encoding]::UTF8
16 | $writer = New-Object System.XMl.XmlTextWriter('./manifest.xml', $encoding)
17 | $writer.Formatting = 'Indented'
18 | $writer.Indentation = 1
19 | $writer.IndentChar = "`t"
20 | $writer.WriteStartDocument()
21 | $writer.WriteStartElement('bundle')
22 | $writer.WriteAttributeString('xmlns', 'http://v8.1c.ru/8.2/addin/bundle')
23 |
24 | $writer.WriteStartElement('component')
25 | $writer.WriteAttributeString('type', 'native')
26 | $writer.WriteAttributeString('os', 'Windows')
27 | $writer.WriteAttributeString('arch', 'i386')
28 | $writer.WriteAttributeString('path', "${project}Win32${postfix}.dll")
29 | $writer.WriteEndElement();
30 |
31 | $writer.WriteStartElement('component')
32 | $writer.WriteAttributeString('type', 'native')
33 | $writer.WriteAttributeString('os', 'Windows')
34 | $writer.WriteAttributeString('arch', 'x86_64')
35 | $writer.WriteAttributeString('path', "${project}Win64${postfix}.dll")
36 | $writer.WriteEndElement();
37 |
38 | $writer.WriteStartElement('component')
39 | $writer.WriteAttributeString('type', 'native')
40 | $writer.WriteAttributeString('os', 'Linux')
41 | $writer.WriteAttributeString('arch', 'i386')
42 | $writer.WriteAttributeString('path', "${project}Lin32${postfix}.so")
43 | $writer.WriteEndElement();
44 |
45 | $writer.WriteStartElement('component')
46 | $writer.WriteAttributeString('type', 'native')
47 | $writer.WriteAttributeString('os', 'Linux')
48 | $writer.WriteAttributeString('arch', 'x86_64')
49 | $writer.WriteAttributeString('path', "${project}Lin64${postfix}.so")
50 | $writer.WriteEndElement();
51 |
52 | $writer.WriteEndElement();
53 | $writer.WriteEndDocument()
54 | $writer.Flush()
55 | $writer.Close()
56 |
--------------------------------------------------------------------------------
/src/AddInNative.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include "../version.h"
4 | #define STRINGIZE2(s) #s
5 | #define STRINGIZE(s) STRINGIZE2(s)
6 |
7 | #ifdef _WINDOWS
8 | #pragma warning (disable : 4267)
9 | #pragma warning (disable : 4302)
10 | #pragma warning (disable : 4311)
11 | #else
12 | #include
13 | #include
14 | #include
15 | #endif
16 |
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | #include "AddInNative.h"
27 |
28 | #ifdef _WINDOWS
29 |
30 | HMODULE hModule = NULL;
31 |
32 | BOOL APIENTRY DllMain(HMODULE module, DWORD ul_reason_for_call, LPVOID lpReserved)
33 | {
34 | switch (ul_reason_for_call)
35 | {
36 | case DLL_PROCESS_ATTACH:
37 | ::DisableThreadLibraryCalls(module);
38 | ::hModule = module;
39 | break;
40 | case DLL_THREAD_ATTACH:
41 | case DLL_THREAD_DETACH:
42 | case DLL_PROCESS_DETACH:
43 | break;
44 | }
45 | return TRUE;
46 | }
47 | #endif
48 |
49 | const WCHAR_T* GetClassNames()
50 | {
51 | static const std::u16string names(AddInNative::getComponentNames());
52 | return (const WCHAR_T*)names.c_str();
53 | }
54 |
55 | long GetClassObject(const WCHAR_T* wsName, IComponentBase** pInterface)
56 | {
57 | if (*pInterface) return 0;
58 | auto cls_name = std::u16string(reinterpret_cast(wsName));
59 | return long(*pInterface = AddInNative::CreateObject(cls_name));
60 | }
61 |
62 | long DestroyObject(IComponentBase** pInterface)
63 | {
64 | if (!*pInterface) return -1;
65 | delete* pInterface;
66 | *pInterface = nullptr;
67 | return 0;
68 | }
69 |
70 | std::string WC2MB(const std::wstring& wstr)
71 | {
72 | std::wstring_convert> converter;
73 | return converter.to_bytes(wstr);
74 | }
75 |
76 | std::wstring MB2WC(const std::string& str)
77 | {
78 | std::wstring_convert> converter;
79 | return converter.from_bytes(str);
80 | }
81 |
82 | std::map AddInNative::components;
83 |
84 | AddInNative::AddInNative(void) : result(nullptr, this) {
85 | AddProperty(u"Version", u"Версия", [&](VH var) { var = this->version(); });
86 | }
87 |
88 | std::string AddInNative::version()
89 | {
90 | return STRINGIZE(VERSION_FULL);
91 | }
92 |
93 | bool AddInNative::Init(void* pConnection)
94 | {
95 | m_iConnect = static_cast(pConnection);
96 | if (m_iConnect) m_iConnect->SetEventBufferDepth(100);
97 | return m_iConnect != nullptr;
98 | }
99 |
100 | bool AddInNative::setMemManager(void* memory)
101 | {
102 | return m_iMemory = static_cast(memory);
103 | }
104 |
105 | long AddInNative::GetInfo()
106 | {
107 | return 2000;
108 | }
109 |
110 | void AddInNative::Done()
111 | {
112 | }
113 |
114 | bool AddInNative::RegisterExtensionAs(WCHAR_T** wsLanguageExt)
115 | {
116 | return *wsLanguageExt = W(name.c_str());
117 | }
118 |
119 | long AddInNative::GetNProps()
120 | {
121 | return properties.size();
122 | }
123 |
124 | long AddInNative::FindProp(const WCHAR_T* wsPropName)
125 | {
126 | std::u16string name((char16_t*)wsPropName);
127 | for (auto it = properties.begin(); it != properties.end(); ++it) {
128 | for (auto n = it->names.begin(); n != it->names.end(); ++n) {
129 | if (n->compare(name) == 0) return long(it - properties.begin());
130 | }
131 | }
132 | name = upper(name);
133 | for (auto it = properties.begin(); it != properties.end(); ++it) {
134 | for (auto n = it->names.begin(); n != it->names.end(); ++n) {
135 | if (upper(*n).compare(name) == 0) return long(it - properties.begin());
136 | }
137 | }
138 | return -1;
139 | }
140 |
141 | const WCHAR_T* AddInNative::GetPropName(long lPropNum, long lPropAlias)
142 | {
143 | try {
144 | auto it = std::next(properties.begin(), lPropNum);
145 | if (it == properties.end()) return nullptr;
146 | auto nm = std::next(it->names.begin(), lPropAlias);
147 | if (nm == it->names.end()) return nullptr;
148 | return W(nm->c_str());
149 | }
150 | catch (...) {
151 | return nullptr;
152 | }
153 | }
154 |
155 | bool AddInNative::GetPropVal(const long lPropNum, tVariant* pvarPropVal)
156 | {
157 | auto it = std::next(properties.begin(), lPropNum);
158 | if (it == properties.end()) return false;
159 | if (!it->getter) return false;
160 | try {
161 | it->getter(VA(pvarPropVal, &(*it)));
162 | return true;
163 | }
164 | catch (const std::u16string& msg) {
165 | AddError(msg);
166 | return false;
167 | }
168 | catch (...) {
169 | return false;
170 | }
171 | }
172 |
173 | bool AddInNative::SetPropVal(const long lPropNum, tVariant* pvarPropVal)
174 | {
175 | auto it = std::next(properties.begin(), lPropNum);
176 | if (it == properties.end()) return false;
177 | if (!it->setter) return false;
178 | try {
179 | it->setter(VA(pvarPropVal, &(*it)));
180 | return true;
181 | }
182 | catch (const std::u16string& msg) {
183 | AddError(msg);
184 | return false;
185 | }
186 | catch (...) {
187 | return false;
188 | }
189 | }
190 |
191 | bool AddInNative::IsPropReadable(const long lPropNum)
192 | {
193 | auto it = std::next(properties.begin(), lPropNum);
194 | if (it == properties.end()) return false;
195 | return (bool)it->getter;
196 | }
197 |
198 | bool AddInNative::IsPropWritable(const long lPropNum)
199 | {
200 | auto it = std::next(properties.begin(), lPropNum);
201 | if (it == properties.end()) return false;
202 | return (bool)it->setter;
203 | }
204 |
205 | long AddInNative::GetNMethods()
206 | {
207 | return methods.size();
208 | }
209 |
210 | long AddInNative::FindMethod(const WCHAR_T* wsMethodName)
211 | {
212 | std::u16string name((char16_t*)wsMethodName);
213 | for (auto it = methods.begin(); it != methods.end(); ++it) {
214 | for (auto n = it->names.begin(); n != it->names.end(); ++n) {
215 | if (n->compare(name) == 0) return long(it - methods.begin());
216 | }
217 | }
218 | name = upper(name);
219 | for (auto it = methods.begin(); it != methods.end(); ++it) {
220 | for (auto n = it->names.begin(); n != it->names.end(); ++n) {
221 | if (upper(*n).compare(name) == 0) return long(it - methods.begin());
222 | }
223 | }
224 | return -1;
225 | }
226 |
227 | const WCHAR_T* AddInNative::GetMethodName(const long lMethodNum, const long lMethodAlias)
228 | {
229 | try {
230 | auto it = std::next(methods.begin(), lMethodNum);
231 | if (it == methods.end()) return nullptr;
232 | auto nm = std::next(it->names.begin(), lMethodAlias);
233 | if (nm == it->names.end()) return nullptr;
234 | return W(nm->c_str());
235 | }
236 | catch (...) {
237 | return nullptr;
238 | }
239 | }
240 |
241 | long AddInNative::GetNParams(const long lMethodNum)
242 | {
243 | auto it = std::next(methods.begin(), lMethodNum);
244 | if (it == methods.end()) return 0;
245 | if (std::get_if(&it->handler)) return 0;
246 | if (std::get_if(&it->handler)) return 1;
247 | if (std::get_if(&it->handler)) return 2;
248 | if (std::get_if(&it->handler)) return 3;
249 | if (std::get_if(&it->handler)) return 4;
250 | if (std::get_if(&it->handler)) return 5;
251 | if (std::get_if(&it->handler)) return 6;
252 | if (std::get_if(&it->handler)) return 7;
253 | return 0;
254 | }
255 |
256 | bool AddInNative::GetParamDefValue(const long lMethodNum, const long lParamNum, tVariant* pvarParamDefValue)
257 | {
258 | try {
259 | VA(pvarParamDefValue).clear();
260 | auto it = std::next(methods.begin(), lMethodNum);
261 | if (it == methods.end()) return true;
262 | auto p = it->defs.find(lParamNum);
263 | if (p == it->defs.end()) return true;
264 | auto var = &p->second.variant;
265 | if (auto value = std::get_if(var)) {
266 | VA(pvarParamDefValue) = *value;
267 | return true;
268 | }
269 | if (auto value = std::get_if(var)) {
270 | VA(pvarParamDefValue) = *value;
271 | return true;
272 | }
273 | if (auto value = std::get_if(var)) {
274 | VA(pvarParamDefValue) = *value;
275 | return true;
276 | }
277 | if (auto value = std::get_if(var)) {
278 | VA(pvarParamDefValue) = *value;
279 | return true;
280 | }
281 | return true;
282 | }
283 | catch (const std::u16string& msg) {
284 | AddError(msg);
285 | return false;
286 | }
287 | catch (...) {
288 | return false;
289 | }
290 | }
291 |
292 | bool AddInNative::HasRetVal(const long lMethodNum)
293 | {
294 | try {
295 | auto it = std::next(methods.begin(), lMethodNum);
296 | if (it == methods.end()) return false;
297 | return it->hasRetVal;
298 | }
299 | catch (...) {
300 | return false;
301 | }
302 | }
303 |
304 | bool AddInNative::CallMethod(MethFunction* func, tVariant* p, Meth* m, const long lSizeArray)
305 | {
306 | if (auto handler = std::get_if(func)) {
307 | (*handler)();
308 | return true;
309 | }
310 | if (auto handler = std::get_if(func)) {
311 | if (lSizeArray < 1) throw std::bad_function_call();
312 | (*handler)(VA(p, m, 0));
313 | return true;
314 | }
315 | if (auto handler = std::get_if(func)) {
316 | if (lSizeArray < 2) throw std::bad_function_call();
317 | (*handler)(VA(p, m, 0), VA(p, m, 1));
318 | return true;
319 | }
320 | if (auto handler = std::get_if(func)) {
321 | if (lSizeArray < 3) throw std::bad_function_call();
322 | (*handler)(VA(p, m, 0), VA(p, m, 1), VA(p, m, 2));
323 | return true;
324 | }
325 | if (auto handler = std::get_if(func)) {
326 | if (lSizeArray < 4) throw std::bad_function_call();
327 | (*handler)(VA(p, m, 0), VA(p, m, 1), VA(p, m, 2), VA(p, m, 3));
328 | return true;
329 | }
330 | if (auto handler = std::get_if(func)) {
331 | if (lSizeArray < 5) throw std::bad_function_call();
332 | (*handler)(VA(p, m, 0), VA(p, m, 1), VA(p, m, 2), VA(p, m, 3), VA(p, m, 4));
333 | return true;
334 | }
335 | if (auto handler = std::get_if(func)) {
336 | if (lSizeArray < 6) throw std::bad_function_call();
337 | (*handler)(VA(p, m, 0), VA(p, m, 1), VA(p, m, 2), VA(p, m, 3), VA(p, m, 4), VA(p, m, 5));
338 | return true;
339 | }
340 | if (auto handler = std::get_if(func)) {
341 | if (lSizeArray < 7) throw std::bad_function_call();
342 | (*handler)(VA(p, m, 0), VA(p, m, 1), VA(p, m, 2), VA(p, m, 3), VA(p, m, 4), VA(p, m, 5), VA(p, m, 6));
343 | return true;
344 | }
345 | return false;
346 | }
347 |
348 | bool AddInNative::CallAsProc(const long lMethodNum, tVariant* paParams, const long lSizeArray)
349 | {
350 | auto it = std::next(methods.begin(), lMethodNum);
351 | if (it == methods.end()) return false;
352 | try {
353 | result << VA(nullptr);
354 | return CallMethod(&it->handler, paParams, &(*it), lSizeArray);
355 | }
356 | catch (const std::u16string& msg) {
357 | AddError(msg);
358 | return false;
359 | }
360 | catch (...) {
361 | return false;
362 | }
363 | }
364 |
365 | bool AddInNative::CallAsFunc(const long lMethodNum, tVariant* pvarRetValue, tVariant* paParams, const long lSizeArray)
366 | {
367 | auto it = std::next(methods.begin(), lMethodNum);
368 | if (it == methods.end()) return false;
369 | try {
370 | result << VA(pvarRetValue);
371 | bool ok = CallMethod(&it->handler, paParams, &(*it), lSizeArray);
372 | result << VA(nullptr);
373 | return ok;
374 | }
375 | catch (const std::u16string& msg) {
376 | AddError(msg);
377 | return false;
378 | }
379 | catch (...) {
380 | result << VA(nullptr);
381 | return false;
382 | }
383 | }
384 |
385 | void AddInNative::SetLocale(const WCHAR_T* locale)
386 | {
387 | std::string loc = WCHAR2MB(locale);
388 | this->alias = loc.substr(0, 3) == "rus";
389 | }
390 |
391 | std::u16string AddInNative::getComponentNames() {
392 | const char16_t* const delim = u"|";
393 | std::vector names;
394 | for (auto it = components.begin(); it != components.end(); ++it) names.push_back(it->first);
395 | std::basic_ostringstream, std::allocator> imploded;
396 | std::copy(names.begin(), names.end(), std::ostream_iterator>(imploded, delim));
397 | std::u16string result = imploded.str();
398 | result.pop_back();
399 | return result;
400 | }
401 |
402 | std::u16string AddInNative::AddComponent(const std::u16string& name, CompFunction creator)
403 | {
404 | components.insert({ name, creator });
405 | return name;
406 | }
407 |
408 | AddInNative* AddInNative::CreateObject(const std::u16string& name) {
409 | auto it = components.find(name);
410 | if (it == components.end()) return nullptr;
411 | AddInNative* object = it->second();
412 | object->name = name;
413 | return object;
414 | }
415 |
416 | void AddInNative::AddProperty(const std::u16string& nameEn, const std::u16string& nameRu, const PropFunction& getter, const PropFunction& setter)
417 | {
418 | properties.push_back({ { nameEn, nameRu }, getter, setter });
419 | }
420 |
421 | void AddInNative::AddProcedure(const std::u16string& nameEn, const std::u16string& nameRu, const MethFunction& handler, const MethDefaults& defs)
422 | {
423 | methods.push_back({ { nameEn, nameRu }, handler, defs, false });
424 | }
425 |
426 | void AddInNative::AddFunction(const std::u16string& nameEn, const std::u16string& nameRu, const MethFunction& handler, const MethDefaults& defs)
427 | {
428 | methods.push_back({ { nameEn, nameRu }, handler, defs, true });
429 | }
430 |
431 | bool ADDIN_API AddInNative::AllocMemory(void** pMemory, unsigned long ulCountByte) const
432 | {
433 | return m_iMemory ? m_iMemory->AllocMemory(pMemory, ulCountByte) : false;
434 | }
435 |
436 | void ADDIN_API AddInNative::FreeMemory(void** pMemory) const
437 | {
438 | if (m_iMemory) m_iMemory->FreeMemory(pMemory);
439 | }
440 |
441 | std::string AddInNative::WCHAR2MB(std::basic_string_view src)
442 | {
443 | #ifdef _WINDOWS
444 | static std::wstring_convert> cvt_utf8_utf16;
445 | return cvt_utf8_utf16.to_bytes(src.data(), src.data() + src.size());
446 | #else
447 | static std::wstring_convert, char16_t> cvt_utf8_utf16;
448 | return cvt_utf8_utf16.to_bytes(reinterpret_cast(src.data()),
449 | reinterpret_cast(src.data() + src.size()));
450 | #endif//_WINDOWS
451 | }
452 |
453 | std::wstring AddInNative::WCHAR2WC(std::basic_string_view src) {
454 | #ifdef _WINDOWS
455 | return std::wstring(src);
456 | #else
457 | std::wstring_convert> conv;
458 | return conv.from_bytes(reinterpret_cast(src.data()),
459 | reinterpret_cast(src.data() + src.size()));
460 | #endif//_WINDOWS
461 | }
462 |
463 | std::u16string AddInNative::MB2WCHAR(std::string_view src) {
464 | #ifdef _WINDOWS
465 | static std::wstring_convert> cvt_utf8_utf16;
466 | std::wstring tmp = cvt_utf8_utf16.from_bytes(src.data(), src.data() + src.size());
467 | return std::u16string(reinterpret_cast(tmp.data()), tmp.size());
468 | #else
469 | static std::wstring_convert, char16_t> cvt_utf8_utf16;
470 | return cvt_utf8_utf16.from_bytes(src.data(), src.data() + src.size());
471 | #endif//_WINDOWS
472 | }
473 |
474 | std::locale locale_ru = std::locale("ru_RU.UTF-8");
475 |
476 | std::u16string AddInNative::upper(std::u16string& str)
477 | {
478 | std::transform(str.begin(), str.end(), str.begin(), [](wchar_t ch) { return std::toupper(ch, locale_ru); });
479 | return str;
480 | }
481 |
482 | std::wstring AddInNative::upper(std::wstring& str)
483 | {
484 | std::transform(str.begin(), str.end(), str.begin(), [](wchar_t ch) { return std::toupper(ch, locale_ru); });
485 | return str;
486 | }
487 |
488 | TYPEVAR AddInNative::VarinantHelper::type()
489 | {
490 | if (pvar == nullptr) throw std::bad_variant_access();
491 | return pvar->vt;
492 | }
493 |
494 | uint32_t AddInNative::VarinantHelper::size()
495 | {
496 | if (pvar == nullptr) throw std::bad_variant_access();
497 | if (pvar->vt != VTYPE_BLOB) throw error(VTYPE_BLOB);
498 | return pvar->strLen;
499 | }
500 |
501 | char* AddInNative::VarinantHelper::data()
502 | {
503 | if (pvar == nullptr) throw std::bad_variant_access();
504 | if (pvar->vt != VTYPE_BLOB) throw error(VTYPE_BLOB);
505 | return pvar->pstrVal;
506 | }
507 |
508 | AddInNative::VarinantHelper& AddInNative::VarinantHelper::operator=(const std::string& str)
509 | {
510 | return operator=(AddInNative::MB2WCHAR(str));
511 | }
512 |
513 | AddInNative::VarinantHelper& AddInNative::VarinantHelper::operator=(const std::wstring& str)
514 | {
515 | if (sizeof(wchar_t) == 2) {
516 | return operator=(std::u16string(reinterpret_cast(str.data()), str.size()));
517 | }
518 | else {
519 | return operator=(WC2MB(str));
520 | }
521 | }
522 |
523 | void AddInNative::VarinantHelper::clear()
524 | {
525 | if (pvar == nullptr) throw std::bad_variant_access();
526 | switch (TV_VT(pvar)) {
527 | case VTYPE_BLOB:
528 | case VTYPE_PWSTR:
529 | addin->FreeMemory(reinterpret_cast(&TV_WSTR(pvar)));
530 | break;
531 | }
532 | tVarInit(pvar);
533 | }
534 |
535 | AddInNative::VarinantHelper& AddInNative::VarinantHelper::operator=(int64_t value)
536 | {
537 | clear();
538 | if (INT32_MIN <= value && value <= INT32_MAX) {
539 | TV_VT(pvar) = VTYPE_I4;
540 | TV_I4(pvar) = (int32_t)value;
541 | }
542 | else {
543 | TV_VT(pvar) = VTYPE_R8;
544 | TV_R8(pvar) = (double)value;
545 | }
546 | return *this;
547 | }
548 |
549 | AddInNative::VarinantHelper& AddInNative::VarinantHelper::operator=(double value)
550 | {
551 | clear();
552 | TV_VT(pvar) = VTYPE_R8;
553 | TV_R8(pvar) = value;
554 | return *this;
555 | }
556 |
557 | AddInNative::VarinantHelper& AddInNative::VarinantHelper::operator=(bool value)
558 | {
559 | clear();
560 | TV_VT(pvar) = VTYPE_BOOL;
561 | TV_BOOL(pvar) = value;
562 | return *this;
563 | }
564 |
565 | AddInNative::VarinantHelper& AddInNative::VarinantHelper::operator=(const std::u16string& str)
566 | {
567 | clear();
568 | TV_VT(pvar) = VTYPE_PWSTR;
569 | pvar->pwstrVal = nullptr;
570 | size_t size = (str.size() + 1) * sizeof(char16_t);
571 | if (!addin->AllocMemory(reinterpret_cast(&pvar->pwstrVal), size)) throw std::bad_alloc();
572 | memcpy(pvar->pwstrVal, str.c_str(), size);
573 | pvar->wstrLen = str.size();
574 | while (pvar->wstrLen && pvar->pwstrVal[pvar->wstrLen - 1] == 0) pvar->wstrLen--;
575 | return *this;
576 | }
577 |
578 | bool AddInNative::AddError(const std::u16string& descr, long scode)
579 | {
580 | std::u16string info = u"AddIn." + name;
581 | return m_iConnect && m_iConnect->AddError(ADDIN_E_IMPORTANT, (WCHAR_T*)info.c_str(), (WCHAR_T*)descr.c_str(), scode);
582 | }
583 |
584 | static std::u16string typeinfo(TYPEVAR vt, bool alias)
585 | {
586 | switch (vt) {
587 | case VTYPE_EMPTY:
588 | return alias ? u"Неопределено" : u"Undefined";
589 | case VTYPE_I2:
590 | case VTYPE_I4:
591 | case VTYPE_ERROR:
592 | case VTYPE_UI1:
593 | return alias ? u"Целое число" : u"Integer";
594 | case VTYPE_BOOL:
595 | return alias ? u"Булево" : u"Boolean";
596 | case VTYPE_R4:
597 | case VTYPE_R8:
598 | return alias ? u"Число" : u"Float";
599 | case VTYPE_DATE:
600 | case VTYPE_TM:
601 | return alias ? u"Дата" : u"Date";
602 | case VTYPE_PSTR:
603 | case VTYPE_PWSTR:
604 | return alias ? u"Строка" : u"String";
605 | case VTYPE_BLOB:
606 | return alias ? u"Двоичные данные" : u"Binary";
607 | default:
608 | return alias ? u"Неопределено" : u"Undefined";
609 | }
610 | }
611 |
612 | std::exception AddInNative::VarinantHelper::error(TYPEVAR vt) const
613 | {
614 | std::basic_stringstream, std::allocator> ss;
615 | if (addin && addin->alias) {
616 | ss << u"Ошибка получения значения";
617 | if (prop) ss << u" при обращении к свойству <" << prop->names[1] << ">";
618 | if (meth) ss << u" при вызове метода <" << meth->names[1] << ">";
619 | if (number >= 0) ss << u" параметр <" << number + 1 << ">";
620 | ss << u" ожидается <" + typeinfo(vt, true) << u">";
621 | if (pvar) ss << u" фактически <" + typeinfo(pvar->vt, true) << u">";
622 | }
623 | else {
624 | ss << u"Error getting value";
625 | if (prop) ss << u" of property <" << prop->names[0] << ">";
626 | if (meth) ss << u" when calling method <" << meth->names[0] << ">";
627 | if (number >= 0) ss << u" parameter <" << number + 1 << ">";
628 | ss << u" expected <" + typeinfo(vt, false) << u">";
629 | if (pvar) ss << u" actual value <" + typeinfo(pvar->vt, false) << u">";
630 | }
631 | if (addin) addin->AddError(ss.str());
632 | return std::bad_typeid();
633 | }
634 |
635 | AddInNative::VarinantHelper::operator std::string() const
636 | {
637 | std::u16string str(*this);
638 | return WCHAR2MB((WCHAR_T*)str.c_str());
639 | }
640 |
641 | AddInNative::VarinantHelper::operator std::wstring() const
642 | {
643 | std::u16string str(*this);
644 | return WCHAR2WC((WCHAR_T*)str.c_str());
645 | }
646 |
647 | AddInNative::VarinantHelper::operator std::u16string() const
648 | {
649 | if (pvar == nullptr) throw std::bad_variant_access();
650 | if (pvar->vt != VTYPE_PWSTR) throw error(VTYPE_PWSTR);
651 | return reinterpret_cast(pvar->pwstrVal);
652 | }
653 |
654 | AddInNative::VarinantHelper::operator int64_t() const
655 | {
656 | if (pvar == nullptr) throw std::bad_variant_access();
657 | switch (TV_VT(pvar)) {
658 | case VTYPE_I2:
659 | case VTYPE_I4:
660 | case VTYPE_UI1:
661 | case VTYPE_ERROR:
662 | return (int64_t)pvar->lVal;
663 | case VTYPE_R4:
664 | case VTYPE_R8:
665 | return (int64_t)pvar->dblVal;
666 | default:
667 | throw error(VTYPE_I4);
668 | }
669 | }
670 |
671 | AddInNative::VarinantHelper::operator int() const
672 | {
673 | if (pvar == nullptr) throw std::bad_variant_access();
674 | switch (TV_VT(pvar)) {
675 | case VTYPE_I2:
676 | case VTYPE_I4:
677 | case VTYPE_UI1:
678 | case VTYPE_ERROR:
679 | return (int)pvar->lVal;
680 | case VTYPE_R4:
681 | case VTYPE_R8:
682 | return (int)pvar->dblVal;
683 | default:
684 | throw error(VTYPE_I4);
685 | }
686 | }
687 |
688 | AddInNative::VarinantHelper::operator double() const
689 | {
690 | if (pvar == nullptr) throw std::bad_variant_access();
691 | switch (TV_VT(pvar)) {
692 | case VTYPE_I2:
693 | case VTYPE_I4:
694 | case VTYPE_UI1:
695 | case VTYPE_ERROR:
696 | return (double)pvar->lVal;
697 | case VTYPE_R4:
698 | case VTYPE_R8:
699 | return (double)pvar->dblVal;
700 | default:
701 | throw error(VTYPE_R4);
702 | }
703 | }
704 |
705 | AddInNative::VarinantHelper::operator bool() const
706 | {
707 | if (pvar == nullptr) throw std::bad_variant_access();
708 | switch (TV_VT(pvar)) {
709 | case VTYPE_BOOL:
710 | return TV_BOOL(pvar);
711 | case VTYPE_I2:
712 | case VTYPE_I4:
713 | case VTYPE_UI1:
714 | case VTYPE_ERROR:
715 | return (bool)pvar->lVal;
716 | default:
717 | throw error(VTYPE_BOOL);
718 | }
719 | }
720 |
721 | void AddInNative::VarinantHelper::AllocMemory(unsigned long size)
722 | {
723 | clear();
724 | if (!addin->AllocMemory((void**)&pvar->pstrVal, size)) throw std::bad_alloc();
725 | TV_VT(pvar) = VTYPE_BLOB;
726 | pvar->strLen = size;
727 | }
728 |
729 | WCHAR_T* AddInNative::W(const char16_t* str) const
730 | {
731 | WCHAR_T* res = NULL;
732 | size_t length = std::char_traits::length(str) + 1;
733 | unsigned long size = length * sizeof(WCHAR_T);
734 | if (!AllocMemory((void**)&res, size)) throw std::bad_alloc();
735 | memcpy(res, str, size);
736 | return res;
737 | }
738 |
739 |
--------------------------------------------------------------------------------
/src/AddInNative.def:
--------------------------------------------------------------------------------
1 | EXPORTS
2 | GetClassObject
3 | DestroyObject
4 | GetClassNames
5 |
--------------------------------------------------------------------------------
/src/AddInNative.h:
--------------------------------------------------------------------------------
1 | #ifndef __ADDINNATIVE_H__
2 | #define __ADDINNATIVE_H__
3 |
4 | #ifdef _WINDOWS
5 | #include
6 | #endif //_WINDOWS
7 |
8 | #include