0. Evil Beaver 6290 22.04.13 12:41 Сейчас в теме

NativeAPI. Внешние компоненты на С++ "для чайников"

В жизни каждого 1С-ника наступает момент, когда для выполнения задачи требуется код на другом языке программирования. На помощь приходят внешние компоненты, но как их писать, если последний раз вы брались за другой язык сто лет назад, сортируя массивы пузырьком на лабораторках в ВУЗе? Можно быстренько узнать только самое нужное, прочитав эту статью.

Перейти к публикации

Комментарии
Избранное Подписка Сортировка: Древо
1. BorisMor 302 23.04.13 04:09 Сейчас в теме
Ну все... на майские праздники есть в чем разобраться)
2. vasbur 23.04.13 07:22 Сейчас в теме
А можете рассказать, как из С++ в 1С вернуть пустую дату?
Чтобы и на 7.7 и на 8.2 правильно работало
3. andrewks 1269 23.04.13 07:31 Сейчас в теме
(2) vasbur, для 8-ки 0001.01.01 0:00:00
4. vasbur 23.04.13 07:36 Сейчас в теме
(3) Это в 1С.
А как это в С++ написать?
6. vasbur 23.04.13 08:12 Сейчас в теме
(5) Вобщем, дату "0001.01.01" не вернуть никак
7. andrewks 1269 23.04.13 08:18 Сейчас в теме
8. DoctorRoza 23.04.13 08:23 Сейчас в теме
Хорошо написано, тем более, что 2-3-мя строчками кода тут не обойдешься. Но все-таки, сорцы нужно выкладывать, не жмотся, Автор! :)
9. Evil Beaver 6290 23.04.13 10:02 Сейчас в теме
(8) DoctorRoza, ну сорцы как бы на ИТС. Они у всех есть, чего их выкладывать?
25. a-novoselov 1088 26.04.13 11:34 Сейчас в теме
(9) Ну "ИТС есть у всех" это не всегда правда, например, на работе есть, а дома нет. И чтобы дома попробовать, придется искать этот ИТС. Тем более за скачанные файлы вам $m будут капать, так что лучше бы выложили... Можно даже со своими комментариями, объясняющими для чайников назначение той или иной функции и ее параметров (особенно если не понятно из названия).
А в целом статья полезная, однозначно +
10. dyak84 23.04.13 10:27 Сейчас в теме
Очень интересно. Автору огромное спасибо. Есть над чем поработать на выходных
11. AlexanderKai 23.04.13 10:38 Сейчас в теме
Классная статья, разжевано даже для самых ленивых. Теперь не надо ничего искать, когда потребуется вдруг внешнюю компоненту написать :)
12. le_ 201 23.04.13 10:53 Сейчас в теме
Слегка сумбурно на мой взгляд. Но идея хорошая.
Я думаю, всем было бы понятнее, если бы автор на конкретных примерах показывал как реализовать необходимые в большинстве случаев механизмы.

Моё субъективное мнение таково, что у тех, на кого ориентирована эта статья ("чайники"), если они возьмутся писать компоненту, в процессе обязательно возникнет ряд вопросов, типа, "как вернуть из компоненты значение" и даже не какое-нибудь хитрое, а просто строку. В шаблоне нет такого примера (именно примера) и в этой статье нет. Тип tVariant упомянут вскользь. 1С-ники зачастую вообще забывают о том, что существуют какие-то типы данных. Передача параметров по ссылке, по указателю, по значению - что это такое? )

Предполагаю так же, что возникнут сложности с передачей параметров в компоненту. Как получить и обработать несколько строковых параметров в компоненте? Да, это скорее вопросы программирования на С++ и к технологии компонент имеют опосредованное отношение, но ориентация-то на "чайников".

Как задать параметры по-умолчанию? Как обработать исключительные ситуации? Как сохранить значения для использования при следующем использовании компоненты? Как создать свою форму? Для чего нужен менеджер памяти?

Всё-таки, много вопросов осталось нераскрытыми )
Gendelf; гвость; KroVladS; chizh.84; ilyanet; proal; iov; CratosX; xomaq; адуырщдв; BorisMor; +11 Ответить
13. Evil Beaver 6290 23.04.13 13:23 Сейчас в теме
(12) le_, замечания по существу, спасибо. Только вот с этим немного несогласен:
"как вернуть из компоненты значение" и даже не какое-нибудь хитрое, а просто строку. В шаблоне нет такого примера (именно примера) и в этой статье нет


Как раз это есть. Там где возвращаются двоичные данные, вместо BLOB нужно просто задать тип PSTR.
Но вообще, говоря, вы правы. Нужен краткий справочник howto для типовых действий. Подумаю над продолжением.
14. le_ 201 23.04.13 13:38 Сейчас в теме
(13) Просто имеет смысл акцентировать внимание на том, что и для возвращения строки, обязательно указывать её размер в байтах. Для ASCII один символ - это один байт, а для unicode - 2 байта. Для 1С-ников это непривычно...
16. andrewks 1269 23.04.13 13:53 Сейчас в теме
(14) le_, и + память под строку выделять менеджером памяти 1С, а не сишным
18. Evil Beaver 6290 23.04.13 14:15 Сейчас в теме
(16) andrewks, про менеджер вроде много говорил, что им нужно выделять. Непонятно получилось?
19. andrewks 1269 23.04.13 14:23 Сейчас в теме
(18) если честно, статью смотрел строку через пять ;-)
17. Evil Beaver 6290 23.04.13 14:14 Сейчас в теме
(14) le_, там вроде бы в варианте есть два отдельных размера. Для char - strLen, для wchar - wlen не помню, как то так. Указываем все время в символах и не паримся.
20. andrewks 1269 23.04.13 14:25 Сейчас в теме
(17) совершенно верно, но память нужно выделять в байтах :)
21. CratosX 106 24.04.13 03:20 Сейчас в теме
Достойно!

(12) Le_, на инфостарте уже немного есть пошаговых инструкций. Например, тут, или вот оптом в google MS Visual Studio 1С & внешняя.
Но, у Evil Beaver получилось неплохо, с неплохим оформлением.
15. kng67 23.04.13 13:45 Сейчас в теме
Тема интересная.
Мой коллега пишет внешние компоненты на С++ для 1С.
22. Oleg1708 24.04.13 15:58 Сейчас в теме
Спасибо, понравилось. Вспомнил С++... :)
23. _LEV_ 24.04.13 16:36 Сейчас в теме
Полезно, есть что вспомнить и освежить. Спасибо.
24. ranger 120 26.04.13 08:19 Сейчас в теме
Автору спасибо за кропотливую работу.
Но мне без базовых знаний С++ как-то сложно читается к сожалению:(
26. oleg_km 01.05.13 08:25 Сейчас в теме
Если это широкая строка (VTYPE_PWSTR), то выполняется преобразование сначала к wchar_t, а затем к char. Дело в том, что нам из языка 1С в данный метод передается путь к файлу, который затем используется в функции fopen(char*). Эта функция на вход требует тип char*, а из платформы к нам придет WCHAR_T. Для корректной работы и выполняются преобразования строк.


Внутри C++ тоже удобнее работать с двубайтовыми строками. Проект скомпилировать с опцией UNICODE и автоматом будут использоваться W-варианты функций WinAPI. Например для работы с файлами гораздо удобнее пользовать класс:

#include <atlfile.h>
CAtlFile oFile;
HRESULT nRes = oFile.Create(cSrc, GENERIC_READ, 0, OPEN_EXISTING);
nRes = oFile.Read(cBuff, nSize, nGet);
27. Evil Beaver 6290 01.05.13 23:50 Сейчас в теме
(26) oleg_km, тут вся свистопляска из-за линукса. Там нет винапи, а wchar_t, говорят, четырехбайтовый. Вот и сделали обертку WCHAR_T, чтобы всегда и везде была 2 байта. Но ее в wcslen не передашь, поэтому внутри компоненты - компот из разных строк.
28. Borometr 35 06.05.13 07:57 Сейчас в теме
Недавно начал изучать C#, оказывается не зря, пригодиться и в работе с 1С
59. AlexO 127 23.03.15 16:20 Сейчас в теме
(28) Borometr,
Недавно начал изучать C#, оказывается не зря
Си и C# - это разные языки.
(45) Abadonna,
Как гляну на сишный код, аж передергивает
А от одноэсового? ))
(57)
И где она у вас там?
Это специально виндовую кодировку подключает в Линкус, чтобы с 1С работать можно было нормально. Иначе - будет опа и никаких ВК.
(0) автор, а какие-либо компоненты сами по себе будут? Никак не найду задач, чтобы писать ВК ))
29. CratosX 106 06.05.13 15:14 Сейчас в теме
(0), скачал ваш шаблон, попробовал открыть в
Microsoft Visual Studio Express 2012 для Windows Desktop
Версия 11.0.50727.42 VSLRSTAGE
Microsoft .NET Framework
Версия 4.5.50709

Visual C++ 2012 05695-004-0030004-02855
Microsoft Visual C++ 2012

На Windows 7 pro x32.
Дело в версии MS Visual Studio или в Visual C++?
Но это пол беды. Следуя статье, наткнулся на то, что в файле AddInNative.def нет того кода, что приведён в статье. Предлагается ввести его самостоятельно?
Естественно, компиляция выдаёт кучу ошибок, но думаю до их разбора пока далеко. Что делаю не так?
Прикрепленные файлы:
UpgradeLog.XML
30. Evil Beaver 6290 06.05.13 15:44 Сейчас в теме
(29) CratosX, на вашем рисунке файл *.def содержит все, что нужно - три обязательных экспорта. В статье они описаны. Сам вложенный файл - это фрагмент шаблона компоненты с диска ИТС, прикрепил "как есть", вроде бы он нормально собирался, без проблем. Копайте причины ошибок.

Что делаю не так?

Как минимум не сообщаете точные тексты ошибок. Телепат был только у г-на Орефкова и то для 7.7 :)
31. CratosX 106 06.05.13 15:47 Сейчас в теме
(30) в посте прикрепил один файлик - UpgradeLog.XML, он довольно объёмный и не счёл нужным приводить его в текстовом виде
32. Evil Beaver 6290 06.05.13 15:52 Сейчас в теме
(31) CratosX, да, но это лог конвертации проекта из одной версии "студии" в другую. Поэтому сразу в него не посмотрел, ожидал ошибок именно сборки, а не upgrade проекта. Тем не менее, как я и предполагал, студия жалуется на возможные проблемы с линковкой. Разбирайтесь с настройками проекта, чего-то там не срастается с библиотеками.
33. CratosX 106 06.05.13 17:03 Сейчас в теме
(32) тогда скажите версию своей MS Visual Studio. Да и Windows наверняка x64?
34. CratosX 106 06.05.13 20:40 Сейчас в теме
(32) с этим разобрался - файлы из папки include надо было скопировать в папку основного проекта.
Теперь при построении выдаёт следующее:
1>------ Перестроение всех файлов начато: проект: AddInNative, Конфигурация: Debug Win32 ------
1>  stdafx.cpp
1>  AddInNative.cpp
1>  dllmain.cpp
1>AddInNative.obj : warning LNK4075: не учитывается "/EDITANDCONTINUE" из-за спецификации "/SAFESEH"
1>     Создается библиотека D:\Share\Ext\NativeAPI\vncomp_public\NativeAPI__\\bind\AddInNa­tive.lib и объект D:\Share\Ext\NativeAPI\vncomp_public\NativeAPI__\\bind\AddInNa­tive.exp
1>  AddInNative.vcxproj -> D:\Share\Ext\NativeAPI\vncomp_public\NativeAPI__\\bind\AddInNa­tive.dll
========== Перестроение всех: успешно: 1, с ошибками: 0, пропущено: 0 ==========
,
а при отладке ругается на неправильный путь к dll. Где копать?
Прикрепленные файлы:
35. CratosX 106 07.05.13 16:55 Сейчас в теме
Думаю, проблема в параметрах компиляции, но как правильно изменить пути, не знаю

UPD: Решено, в моих глобальных переменных параметр $(SolutionDir) оканчивается на слэш. В итоге требовалось изменить строку параметра на $(SolutionDir)bind\
Прикрепленные файлы:
36. Evil Beaver 6290 07.05.13 18:02 Сейчас в теме
(35) CratosX, у вас же все нормально собралось, ошибок сборки нет. В чем беда-то? Что отладка не стартует? Дык это ж DLL. Она ж не умеет стартовать сама по себе. Она же только из какого-то процесса другого может работать. Вы ее втупую из 1С пробовали вызывать?
Обычно мне помогает гуглить по точному тексту ошибки. Удивительно, но в интернетах почти на все вопросы уже есть ответ.
37. CratosX 106 07.05.13 18:41 Сейчас в теме
(36) так я и спрашиваю как новичок новичка :-)
DLL-ку я увидел, и использовать из 1С - это дело второе.
Беда в том, что смущало это сообщение, прямое гугление по тексту ошибок навело на неверные параметры настройки компиляции. Ну, не вы, так кто-нибудь другой может подскажет - вдруг это фишка 2012-го MS VS?

Да, пытаюсь из 1С обратиться к компоненте
ПодключитьВнешнююКомпоненту(ПутьФайла, "МояКомпонента", ТипВнешнейКомпоненты.Native);
ОбъектКомпоненты = Новый("AddIn.МояКомпонента.AddInNativeExtension");

Из статьи не совсем понял, как обращаться к методам этой ВК
Прикрепленные файлы:
38. Evil Beaver 6290 08.05.13 09:55 Сейчас в теме
(37) CratosX, к методам обращаться прям как они описаны внутри компоненты. В примере имена методов строками прям в начале файла идут. Из 1С их по этим именам и вызывать:

ОбъектКомпоненты.МойМетод();
39. CratosX 106 08.05.13 10:40 Сейчас в теме
(38) слона-то я и не заметил. Спасибо!
40. CratosX 106 08.05.13 13:01 Сейчас в теме
(38) в статье есть неточность - заявлены методы
Методы:
Включить/Enable;
Выключить/Disable;
ПоказатьВСтрокеСтатуса/ShowInStatusLine;
ВключитьТаймер/StartTimer;
ВыключитьТаймер/StopTimer;
ЗагрузитьКартинку/LoadPicture;

Но в самой ВК используются
static wchar_t *g_MethodNamesRu[] = {L"Включить", L"Выключить", L"ПоказатьВСтрокеСтатуса",
L"СтартТаймер", L"СтопТаймер", L"ЗагрузитьКартинку"};


Если кому интересно - вот заготовка для теста из 1С
Прикрепленные файлы:
ВнешняяКомпонента_Cratos.epf
AnL24; Tandery; KroVladS; quebracho; +4 Ответить
43. quebracho 24 29.06.13 15:29 Сейчас в теме
(40) CratosX,
А вот версия обработки с "живым" таймером :)
+ dll
Прикрепленные файлы:
ВнешняяКомпонента_Cratos.epf
AddInNative.dll
zarazka_kate; maslov.pav; KroVladS; CratosX; +4 Ответить
41. Alex1Cnic 22.05.13 10:45 Сейчас в теме
Интересая публиация, но можно ли сделать подобное для Delphi(RadSudio XE)?
46. Abadonna 3833 29.07.13 19:26 Сейчас в теме
(41) ProFix1c, вот это спасет отца русской демократии ;)
http://infostart.ru/public/81644/
47. Evil Beaver 6290 29.07.13 22:45 Сейчас в теме
(46) как вспомню паскальное присваивание через двоеточие, аж передергивает. Но зач0т, все равно)
49. Alex1Cnic 124 30.07.13 07:58 Сейчас в теме
(46) Abadonna,
респект, то, что надо!
42. Alex1Cnic 22.05.13 10:47 Сейчас в теме
Мне Delphi ближе к телу....а С++ что-то пока не освою...
44. Boudybuilder 60 15.07.13 15:25 Сейчас в теме
Супер статейка!
Автору спасибо!
45. Abadonna 3833 29.07.13 19:17 Сейчас в теме
Как гляну на сишный код, аж передергивает :)))
Но плюс все равно.
48. quebracho 24 30.07.13 07:37 Сейчас в теме
Чтобы ногу свело, вспомните prolog.
50. KroVladS 32 21.08.13 14:41 Сейчас в теме
Большое спасибо.
Усиленно ковыряю, пока не очень понятно. Но очень занимательно.
51. androgin 20.08.14 19:22 Сейчас в теме
Я только не понимаю, как скомпилировать компоненту для вебклиента
нигде не нашел мануалов с описанием/картинками..
подскажите...
KroVladS; +1 Ответить
52. MishaHD 28 17.10.14 13:53 Сейчас в теме
Доброго времени суток, в статье часто упоминается "документация". Но вот где ее найти? Что-то в web итс и на дисках вообще не густо информации. Например вообще не нашел инфы по поводу m_iConnect например. Подскажите где искать плиз.
55. Evil Beaver 6290 28.10.14 16:58 Сейчас в теме
(52) MishaHD, Материал на ИТС называется "Технология создания внешних компонент"
53. buganov 59 27.10.14 18:40 Сейчас в теме
А кто знает можно ли как-нибудь отладить ВК в VS 2012?
54. Evil Beaver 6290 28.10.14 16:57 Сейчас в теме
(53) buganov, запускаете Предприятие, потом в Студии делаете меню "DEBUG\Attach to process". Выбираете процесс отлаживаемого Предприятия.
В студии ставите точку останова, а в Предприятии вызываете вашу компоненту. Профит.
jif; buganov; +2 Ответить
56. sikuda 580 18.03.15 09:48 Сейчас в теме
мои пару замечаний по внешним компонентам 1C:
1. Используем кодировку 1251. В Windows неявно, а в Linux makefile: -finput-charset=WINDOWS-1251
При сборке на Windows 10(Visual Studio 2008) перестают работать русские методы внешней компоненты.
2. Форматы динамических библиотек для разных компиляторов не совпадают, поэтому собираем компоненту в Windows только в Visual Studio(никакого MinGW),а Linux gcc.
57. Evil Beaver 6290 18.03.15 12:27 Сейчас в теме
(56) sikuda, что значит "используем кодировку"? А зачем вы именно ее используете, какая с этого выгода? Если вы прицеливаетесь на Линукс, то на кой ляд вам там кодировка windows-1251. И где она у вас там?
58. AlexanderKai 23.03.15 15:57 Сейчас в теме
(56) sikuda,
Почему никакого mingw? MinGW умеет собирать .dll.
78. PerlAmutor 45 31.01.18 14:08 Сейчас в теме
(58) Потому, что собирать собирает, а работать не работает. Исключение возникает. Тем более, что если .dll тянет какую-нибудь другую .dll с собой, то её уже никак не запакуешь вместе с родительской, 1С не находит.
60. Гость 12.07.15 22:53
Добавлю пару особенностей.
Первое: указывать версию 2000 обязательно. Иначе следующий код выведет не "1; 2", как ожидается, а "2; 2" (т. е. Объект1 и Объект2 будут на самом деле ссылками на один и тот же объект):
ПодключитьВнешнююКомпоненту("AddInNative.dll", "TestComponent", ТипВнешнейКомпоненты.Native);
	
Объект1 = Новый("AddIn.TestComponent.TestExtension");
Объект1.ЦелоеЧисло = 1;
	
Объект2 = Новый("AddIn.TestComponent.TestExtension");
Объект2.ЦелоеЧисло = 2;
	
Сообщить(Объект1.ЦелоеЧисло);
Сообщить(Объект2.ЦелоеЧисло);
Показать


Мне лично это немало крови попортило - свою компоненту писал копипастом с чужой, где версия по неизвестной причине стояла 1000.

И второе: конструктор класса CAddinNative вызовется первый раз при первом вызове
ПодключитьВнешнююКомпоненту("AddInNative.dll", "TestComponent", ТипВнешнейКомпоненты.Native);

а вот при первом вызове
Новый("AddIn.TestComponent.TestExtension");

не произойдет вообще ничего. Второй вызов "Новый" отработает уже как ожидается - т. е. вызовет конструктор CAddinNative.
baton_pk; +1 Ответить
61. identificator 18 04.09.15 09:32 Сейчас в теме
Кто знает, как получить путь к директории, в которой лежит вызываемая DLL?
В обязательных функциях для стандарта 1С Совместимо указана функция ПолучитьПараметры(GetParameters).
Ее параметром является XML таблица. Я отдельно вынес эту таблицу в XML файл, который положил рядом с DLL.
А в функции GetParameters указываю путь к этому файлу и преобразовываю его содержимое в тип std::wstring.
Не получается указать относительный путь к файлу TableParameters.xml. Потому что рабочая директория вызываемой DLL ссылается на директорию BIN, где лежит 1Сv8.exe.
Если компонента по технологии Native API не требует регистрации в реестре с помощью regsvr32.exe, то вопрос - а как получить путь до этой DLL?
Потому что подключать к 1С, все время указывая абсолютный путь - неправильно, ведь пользователь может куда угодно положить эту DLL.
bool CAddInNative::GetParameters(tVariant* xml_f)
{
	// 1С ПолучитьПараметры
	// считываем xml файл и записываем в строку
	_setmode(_fileno(stdout), _O_U16TEXT);

	const wchar_t filePath[] = L"\\TableParameters.xml"; //-это путь к таблице параметров, но это неверно, нужен абсолютный путь
	std::wstring text1 = LoadText1(filePath);
	
	wstring_to_p(text1, xml_f);
	return true;
}
Показать

И в статье приводится код
ПодключитьВнешнююКомпоненту(ПутьФайла, "МояКомпонента", ТипВнешнейКомпоненты.Native);

Переменная ПутьФайла - откуда заполняется? Как узнать путь???
62. Evil Beaver 6290 04.09.15 11:22 Сейчас в теме
(61) identificator, если я правильно понял, то вот:
HMODULE GetCurrentModule()
{ // NB: XP+ solution!
  HMODULE hModule = NULL;
  GetModuleHandleEx(
    GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
    (LPCTSTR)GetCurrentModule,
    &hModule);

  return hModule;
}

bool CAddInNative::GetParameters(tVariant* xml_f)
{
   LPTSTR buffer; // не забыть выделить памяти
   int bufferLen;

   HMODULE hCurrent = GetCurrentModule();
   GetModuleFileName(hCurrent, buffer, bufferLen);
}

Показать


Естественно, не проверял, но люди пишут, что работает )
identificator; +1 Ответить
63. identificator 18 04.09.15 15:39 Сейчас в теме
(62) спасибо, получилось!
А как быть с функцией?
ПодключитьВнешнююКомпоненту(ПутьФайла, "МояКомпонента", ТипВнешнейКомпоненты.Native);

Как после установки в 1С своего драйвера оборудования потом обращаться к нему?
1С сама запишет драйвер в двоичный макет после добавления драйвера?
Или можно в качестве пути указать имя компоненты?
64. flyer 222 23.01.17 11:22 Сейчас в теме
кто нибудь использовал внешние компоненты для мобильной платформы 1с? на андроиде например.
сам пробую что то не могу с ИТС запустить приложение Шагомер. не хочет проходить инициализация
ВК = Новый ("AddIn.com_1c_StepCounter.com_1c_StepCounterExtension");
65. KroVladS 32 12.04.17 09:56 Сейчас в теме
Есть такая-же статья про создание компоненты для веб клиента?
66. Evil Beaver 6290 15.04.17 02:09 Сейчас в теме
(65) я не разбирался, но по-моему, там же в шаблоне компонент есть примеры для веб-клиента. А бизнес-логика общая в одной dll для всех браузеров
67. karpik666 2716 27.05.17 19:26 Сейчас в теме
Здравствуйте, я сделал native компоненту по шаблону в Итс, все работает, однако столкнулся с проблемой, мне необходимо, чтобы параметр, который передается в функцию компоненты, мог быть изменен. т. e. функция внешней компоненты фактически возвращала Несколько значений.
Например,
лКомпонента = Новый ("Addin.МояКомпонента");
лСумма = 0;
Если лКомпонента.Рассчитать(лСумма) Тогда
Сообщить(лСумма);
КонецЕсли;
68. Evil Beaver 6290 28.05.17 07:54 Сейчас в теме
(67) так можно сделать, в чем сложность, что не получилось?
69. karpik666 2716 28.05.17 08:07 Сейчас в теме
(68) я просто не знаю как передать значение по ссылке, т.е. я могу вернуть значение при выполнении функции - return ret, в типовых примерах я не нашел такой возможности. Вот к примеру
bool CAddInNative::CallAsFunc(const long lMethodNum,
                tVariant* pvarRetValue, tVariant* paParams, const long lSizeArray)
{   switch(lMethodNum)
	{
		case eMethGetDescription:
               bool ret = true;
	}
	
	TV_VT(pvarRetValue) = VTYPE_BOOL;
	TV_BOOL(pvarRetValue) = true;

    return ret; 
}

Показать


Как переделать данную функцию так. чтобы в параметре paParams поменялось одно или несколько входящих в него значений?
70. Evil Beaver 6290 28.05.17 08:12 Сейчас в теме
(69) да точно так же, как в возвращаемом значении. Вам надо в массиве параметров paParams по нужному индексу прописать выходное значение.

Что-то вроде paParams[1] = myVariantValue;

Навскидку не помню, возможно, есть еще настроечный метод про выходные параметры (по аналогии с HasRetValue и IsPropReadable) По-моему, нет такого, но лучше уточнить.
71. karpik666 2716 28.05.17 08:16 Сейчас в теме
(70) делал так
	TV_VT(paParams+1) = VTYPE_PSTR;
			TV_STR(paParams+1) -> pstrVal = "ОПИСАНИЕ";

Но что-то не заработало.
Не хватает знаний C++, может знаете где можно увидеть тогда пример передачи такого параметра? в типовых на ИТС, такого нет
72. Evil Beaver 6290 28.05.17 08:44 Сейчас в теме
(71) Первое: кажется, что неправильно писать TV_STR()->pstrVal, т.к. этот макрос уже возвращает свойство pstrVal.

т.е. нужно писать TV_STR(&paParams[1]) = "ОПИСАНИЕ".

Второе: строчка выше неверна еще и потому, что текст "ОПИСАНИЕ" должен быть выделен менеджером памяти платформы, а не на стеке.

Ну и третье: не хватает указания длины строки. Нужно еще присваивание pstrLen (или как там от называется в Variant)
73. karpik666 2716 28.05.17 09:04 Сейчас в теме
(72) спасибо, а как выделить значение в памяти? для меня это темный лес. по остальному вроде понятно.
75. Evil Beaver 6290 29.05.17 21:59 Сейчас в теме
(73) смотрите примеры выше и код шаблона. m_iMemory->AllocMemory вот такие вот строчки.
karpik666; +1 Ответить
76. karpik666 2716 30.05.17 04:26 Сейчас в теме
(75) хорошо, большое спасибо.
74. KazanKokos 8 28.05.17 17:35 Сейчас в теме
77. Goblin26 02.11.17 13:27 Сейчас в теме
Добрый день.
Пытаюсь скомпилировать компоненту в VisuaiStudio 2013. Все отрабатывает без ошибок. Компонента на локальной машине запускается.
Но при попытке подключить на сервере метод
 ПодключитьВнешнююКомпоненту("ОбщийМакет.Компонента", "AddInNativeExtension", ТипВнешнейКомпоненты.Native)

возвращает Ложь.

Как пример брал исходники с сайта ИТС. Компилировал и как 32-битну и 64. Все равно. Есть подозрение что проблема в настойках студии, вот только в каких не понимаю.
Компилировал на машине где стоит виндовз 10. На сервере серверная винда 2012
79. zels 169 27.02.18 06:56 Сейчас в теме
Как по dll-файлу определить, сделан он как com-компонента или как native?
80. Evil Beaver 6290 27.02.18 10:04 Сейчас в теме
(79) Средствами проводника? Никак. Более того, в одном и том же файле может быть и то, и другое.
81. androgin 27.02.18 17:46 Сейчас в теме
Объясните тупому, как скомпилировать компоненту для Х64 архитектуры?
82. Evil Beaver 6290 27.02.18 22:37 Сейчас в теме
83. androgin 28.02.18 01:45 Сейчас в теме
84. Evil Beaver 6290 28.02.18 12:02 Сейчас в теме
(83) там в настройках конфигурации Debug и Release по-моему архитектура процессора выставляется. Но это не точно
85. androgin 07.03.18 00:40 Сейчас в теме
86. Evil Beaver 6290 07.03.18 10:10 Сейчас в теме
(85) Документация говорит, что это все же где-то там: https://msdn.microsoft.com/en-us/library/ms185328.aspx
87. OldthiefXXX 151 11.07.18 12:56 Сейчас в теме
Все ребята сдаюсь, добавил тестовый метод который просто должен вернуть значение 22 число,

m_iMemory->AllocMemory((void**)&pvarRetValue->pstrVal, 22);
TV_VT(pvarRetValue) = VTYPE_INT;// VTYPE_PWSTR;
pvarRetValue->pstrVal = "22";

В 1с ловлю результат функции неопределенно. Где мой косяк?
88. Evil Beaver 6290 11.07.18 13:08 Сейчас в теме
(87) строкой указал значение же ведь!

TV_VT(pvarRetValue) = VTYPE_INT;// VTYPE_PWSTR; 
TV_I4(pvarRetValue) = 22; // тут число а не строка. И лучше применять макросы TV_

Ах, да. В случае числа - выделять память не надо, выше нужно удалить Alloc
89. OldthiefXXX 151 11.07.18 13:12 Сейчас в теме
БИНГО!
pvarRetValue->vt = VTYPE_I4;
pvarRetValue->lVal = 22;
90. arcadics 6 31.07.18 09:46 Сейчас в теме
"Если наша компонента реализует только один класс (как в примере), то эти функции нужно тупо скопировать к себе."

А как быть когда классов несколько?
long GetClassObject(const wchar_t* wsName, IComponentBase** pInterface)
Создает новый экземпляр класса IComponentBase на основании static const wchar_t g_kClassNames[] = { L"Class1|Class2|Class3" };
при этом DestroyObject(IComponentBase** pIntf) срабатывает для класса созданного в 1С: объект = Новый (Class1);
Остальные классы уничтожаются при закрытии платформы.
При анализе вызова функций в отладчиках 1С и VS я получаю вот такой результат:

ПодключитьВнешнююКомпоненту(ИмяФайла);
GetClassObject для каждого класса g_kClassNames[];
об = Новый ("Class1"); В ВК ничего не происходит. Похоже этой строкой я говорю платформе что работаю в данный момент с Class1.
Если же в этой же обработке вызвать
об1 = Новый ("Class2") т.е. объявить еще одну переменную не уничтожая первую.
Сработает DestroyObject для Class1 !!!
Т.е :

об1 = Новый Class1;
об2 = Новый Class2; ->> DestroyObject(Class1);
об3 = Новый Class3; ->> DestroyObject(Class2);

Вот и получается если после закрытия обработки взывающей процедуру ПодключитьВнешнююКомпоненту в памяти останутся ссылки на объекты созданные GetClassObject они уничтожаться только при закрытии программы.

Пересмотрел множество примеров ВК ответа не нашел. Во всех используется 1 класс.
В документации Class1 связывается с фразой "Расширение". Ок. Расширение для одного основного класса. Но как расширять если платформа для каждого расширения требует ссылку на новый IComponentBase?
91. Evil Beaver 6290 31.07.18 10:55 Сейчас в теме
Да, вызовы конструкторов-деструкторов в платформе выглядят странновато.

Я сейчас точно уже не вспомню, по-моему, порядок такой:

1. Без создания всяких объектов со стороны кода 1С платформа при подключении компоненты вызовет создание класса (всех классов?)
2. Если создать из кода объект, то платформа не вызовет CreateObject (похоже, она вернет тот, первый созданный экземпляр, который запросила неявно в п.1)
3. Все последующие создания классов работают ожидаемо по цепочке Create/Destroy
4. Экземлпяр класса созданный в п.2 также уничтожается по счетчику ссылок и для него вызывается Destroy, если он вышел за пределы видимости
5. Если пункт 2 не выполнялся, т.е. мы подключили компоненту, но объектов не создавали, то Destroy для первого неявного объекта (объектов?) вызовется только при закрытии платформы.

Это наблюдалось на какой-то из 8.2, потом могло измениться.

И за давностью лет мог что-то напутать. Короче говоря, совершенно точно существует неявно созданный объект, который потом платформой уничтожается. НО все объекты созданные из кода Новый() работают ожидаемо - живут пока на них есть ссылки и уничтожаются при обнулении счетчика ссылок. Неявный объект точно не живет все время работы клиента 1С, но поведение по его созданию/уничтожению выглядит необычно и требует доп.исследований
92. arcadics 6 01.08.18 13:39 Сейчас в теме
(91)
но объектов не создавали, то Destroy для первого неявного объекта (объектов?) вызовется только при закрытии платформы.


Логичнее дать возможность программисту 1С создавать и уничтожать объекты (Новый Класс, Класс = Неопределенно).
Сейчас создаются все экземпляры IComponentBase на этапе подключения.
Если например имеется Class1|Class2, а пользователь после после подключения ВК работал с Class2, Class1 после закрытия обработки так и будет висеть в памяти до закрытия платформы. И уничтожить его средствами 1С не возможно т.к. не было создано с помощью "Новый" для него переменной. Я пытался "подчищать" память сохраняя в ВК указатели на объекты в массиве. При закрытии платформы программа рушится так остаются ссылки в самой платформе.
Может быть я чего то не знаю, или не понимаю в этом функционале.
Можно конечно на это забить. Но что будет если сотня пользователей будут пользоваться ВК подключенной не в процедуре "ПриНачалеРаботыСистемы" а в внешней обработке?

(91)
Неявный объект точно не живет все время работы клиента 1С, но поведение по его созданию/уничтожению выглядит необычно и требует доп.исследований

Точно! Вопрос нужно сформулировать так: Как удалить все неявно созданные объекты при закрытии внешней обработки?
93. Evil Beaver 6290 02.08.18 17:54 Сейчас в теме
94. markers 240 08.08.18 06:49 Сейчас в теме
Уважаемый автор, вы не могли бы подсказать как можно можно вернуть массив (Или в крайнем случае ComSafeArray)? Нашел пример только для COM и код в моём случае не работает (там походу ещё и C++ Builder, а у меня Microsoft C++). Я вообще только второй день осваиваю чуждый для меня язык (хоть и знаком с синтаксисом по PHP). Заранее и больше спасибо!
PS: Если можно вернуть структуру/соответствие, будет ещё лучше!
95. Evil Beaver 6290 09.08.18 14:10 Сейчас в теме
(94) Никак. Массивы ни в компоненту ни из нее возвратить нельзя. Огорчение, но это так.

Ну а в целом, погружаться в NativeApi на второй день изучения С++ - это прям геройство. Успехов! )

P.S. помните, что память сама не освобождается, не используйте new для создания объектов, если не понимаете, как он работает, ну и вообще - лучше подтянуть матчасть.
96. markers 240 10.08.18 03:56 Сейчас в теме
(95) Жаль, спасибо за советы. Я тут пытаюсь передать строку типа char, даже вроде уже и память выделяю для строки, но в 1С всё-равно приходит пустая строка, подскажите плиз, что я делаю не так?
name = "Не удалось подключится к кассе";
m_iMemory->AllocMemory((void**)&(paParams + 3)->pstrVal, sizeof(name));
TV_VT(paParams + 3) = VTYPE_PSTR;
TV_STR(paParams + 3) = name;

Вместо VTYPE_PSTR пробовал использовать VTYPE_PWSTR (И соответственно вместо TV_STR - TV_WSTR), ничего не изменилось, но даже если бы и изменилось, как поменять тип char на wchar_t? В случае простого текста, то я конечно могу написать name = L"текст", но я так же использую стороннюю библиотеку, а она уже возвращает char[256]

Большое спасибо!
102. user1055769 25.09.18 13:33 Сейчас в теме
(95) Андрей, здравствуйте! Я занимаюсь разработкой RFID-оборудования, но тут возникла задача разработать Native компоненту для 1С:). На ИТС ознакомился с требованиями к разработке внешних компонент для RFID-оборудования и обнаружил, что в метод "Подключить" необходимо передавать МАССИВ с параметрами подключения. https://its.1c.eu/db/content/metod8dev/src/platform81/to81/requirements/i81­01599.htm?_=1533301588#%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2%D0%B7%D0%BD%D0%B0%D1%87­%D0%B5%D0%BD%D0%B8%D0%B9 Подобных примеров или каких-либо описаний не нашел.

Если разработчики 1С это требуют, то значит это как-то возможно?
103. leemuar 13.12.18 18:39 Сейчас в теме
(102) предполагаю, что описанная вами компонента создается по технологии COM, а не NativeAPI:

* тип этого параметра в документации указан как "IDispatch",
* выше в указанной вами статье есть фраза "Также драйвер должен поддерживать множественные подключения (в соответствии с идеологией COM технологии)"
104. markers 240 14.12.18 02:13 Сейчас в теме
(102) Не знаю вашей задачи, но обратил внимание что вы смотрите старую инструкцию, если вы планируете разработку для современных конфигураций, то вам необходимо читать это: https://its.1c.ru/db/content/metod8dev/src/developers/additional/guides/i81­04829.htm?_=1544610813#chapter236 и там уже нет ни каких массивов и всё через NativeAPI
Оставьте свое сообщение
Новые вопросы с вознаграждением
Автор темы объявил вознаграждение за найденный ответ, его получит тот, кто первый поможет автору.

Вакансии

Бизнес-архитектор 1С, ведущий консультант
Санкт-Петербург
Полный день

Руководитель проектов 1С
Санкт-Петербург
Полный день

Программист 1C
Москва
зарплата от 100 000 руб. до 150 000 руб.
Полный день

Консультант-методолог 1С
Краснодар
зарплата от 110 000 руб.
Полный день

Консультант 1 С
Краснодар
зарплата от 50 000 руб. до 150 000 руб.
Полный день