Решил посмотреть, как работает внешняя компонента для 1С в Linux-е, благо под рукой уже была настроенная виртуалка с Xubuntu и установленной там платформой 8.3.5.1383.
Скопировал в виртуалку с диска ИТС папку VNCOMP83/example/NativeAPI/, зашёл в эту папку, набрал команду «make» и:
$ make
In file included from AddInNative.cpp:15:0:
AddInNative.h:4:27: фатальная ошибка: ComponentBase.h: Нет такого файла или каталога
компиляция прервана.
make: *** [AddInNative.o] Ошибка 1
Посмотрел, где расположен файл ComponentBase.h — как оказалось, он (и ряд других заголовочных файлов) находится в папке VNCOMP83/include/.
Вывод 1: с диска ИТС нужно копировать 2 папки — VNCOMP83/example/NativeAPI/ и VNCOMP83/include/
Пробую скомпилировать ещё раз:
$ make
In file included from AddInNative.cpp:15:0:
AddInNative.h:73:5: ошибка: «HANDLE» не является именем типа
AddInNative.h:74:5: ошибка: «HANDLE» не является именем типа
…make: *** [AddInNative.o] Ошибка 1
Действительно, в файле AddInNative.h в самом конце присутствуют следующие определения:
HANDLE m_hTimer;
HANDLE m_hTimerQueue;
Linux про тип HANDLE ничего не знает. Смотрю где используются m_hTimer и m_hTimerQueue — они используются в файле AddInNative.cpp — один раз в CAddInNative::CAddInNative(), ещё один раз в CAddInNative::Done() и, наконец, в CAddInNative::CallAsProc(…) в ветках «case eMethStartTimer» и «case eMethStopTimer». Причём в последней процедуре код, связанный с этими переменными, выделен как Windows-специфичный (#ifndef __linux__ … #endif). Отсюда можно сделать вывод, что в других местах разработчики просто забыли выделить код с помощью директив. Сделаем это самостоятельно.
В AddInNative.h меняю:
HANDLE m_hTimer;
HANDLE m_hTimerQueue;
на
#ifndef __linux__
HANDLE m_hTimer;
HANDLE m_hTimerQueue;
#endif
В AddInNative.cpp меняю:
CAddInNative::CAddInNative()
{
m_iMemory = 0;
m_iConnect = 0;
m_hTimerQueue = 0;
}
на
CAddInNative::CAddInNative()
{
m_iMemory = 0;
m_iConnect = 0;
#ifndef __linux__
m_hTimerQueue = 0;
#endif
}
после чего
void CAddInNative::Done()
{
if(m_hTimerQueue )
{
DeleteTimerQueue(m_hTimerQueue);
m_hTimerQueue = 0;
}
}
меняю на
void CAddInNative::Done()
{
#ifndef __linux__
if(m_hTimerQueue )
{
DeleteTimerQueue(m_hTimerQueue);
m_hTimerQueue = 0;
}
#endif
}
Как вариант, можно просто закомментировать «linux-неугодный» код, но тогда исходники перестанут компилироваться под Windows.
Вывод 2: перед компилированием нужно убрать Windows-специфичный код из исходников.
Очередная попытка:
$ make
…
AddInNative.cpp:438:49: ошибка: нет подходящей функции для вызова «IMsgBox::Alert(const wchar_t [3])»
…make: *** [AddInNative.o] Ошибка 1
Тут уже даже разбираться не хочется, поэтому просто в файле AddInNative.cpp в функции CAddInNative::CallAsProc() комментирую строки:
// if (succeed)
// imsgbox->Alert(L»OK»);
// else
// imsgbox->Alert(L»Cancel»);
Вывод 3: перед компилированием нужно убрать ещё кое-какой код.
И ещё раз:
$ CXXFLAGS=»-D __linux__» make
…
g++ -MM -D __linux__ -I../include -m32 -finput-charset=WINDOWS-1251 -fPIC AddInNative.cpp > AddInNative.d
g++ -c -D __linux__ -I../include -m32 -finput-charset=WINDOWS-1251 -fPIC dllmain.cpp -o dllmain.o
g++ -MM -D __linux__ -I../include -m32 -finput-charset=WINDOWS-1251 -fPIC dllmain.cpp > dllmain.d
g++ -c -D __linux__ -I../include -m32 -finput-charset=WINDOWS-1251 -fPIC stdafx.cpp -o stdafx.o
g++ -MM -D __linux__ -I../include -m32 -finput-charset=WINDOWS-1251 -fPIC stdafx.cpp > stdafx.d
g++ -D __linux__ -I../include -m32 -finput-charset=WINDOWS-1251 -fPIC -shared AddInNative.o dllmain.o stdafx.o -o AddInNative.so -lpthread
Аллилуйя!!! Наконец-то, в каталоге появился долгожданный AddInNative.so!!!
Теперь попробую подключить эту внешнюю компоненту. Создаю новую внешнюю обработку, добавляю на форму команду Команда1 и пишу обработчик:
&НаСервере
Процедура Команда1НаСервере()
Ок = ПодключитьВнешнююКомпоненту("/путь/к/файлу/внешней/компонеты/AddInNative.so", "AddInNative", ТипВнешнейКомпоненты.Native);
Если НЕ Ок Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Ошибка подключения ВК!";
Сообщение.Сообщить();
Возврат;
КонецЕсли;
ОбъектВК = Новый("AddIn.AddInNative.AddInNativeExtension");
ДвДанные = ОбъектВК.ЗагрузитьКартинку("/usr/share/backgrounds/space-01.jpg");
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Прочитано байт: " + ДвДанные.Размер();
Сообщение.Сообщить();
КонецПроцедуры
&НаКлиенте
Процедура Команда1(Команда)
Команда1НаСервере();
КонецПроцедуры
И она таки вертится:
(1)Очень ценное и нужное замечание, держите нас в курсе. Весь инфостарт испереживался, я сам как на иголках, нервы на пределе, обновляю страницу, каждые 15секунд, Внимание! Опасный момент! И да! Да дорогие друзья, kostyaomsk таки поставил плюс и оставил об этом комментарий. Как мы все долго этого ждали, этого бесполезного никому не нужного комментария «поставил +». И вот он наконец то! Спасибо тебе kostyaomsk за твой флуд ради флуда.
За статью спасибо, камрад.
Сейчас компоненты забросил, но… чем черт не шутит )
(4) Yagodka.Andrey, если будет интерес — можно будет попробовать скооперироваться.
И вообще, если у кого-нибудь есть какая-нибудь практическая задача — пишите — может что-нибудь сделаем. А то сейчас у меня весь интерес чисто академический (единственный клиент с линуксовым сервером перешёл на винду ещё год назад). ))
(5) Давно мечтаю о telnet’e на сервере. Правда в ВК дуб)
Но очень радостно, что подобные технологии развиваются, а то в моем окружении никто не решился на com в лине)
(6) vslimv, ну на com в лине не решился даже microsoft ))
А какую задачу хочется решить с помощь telnet’а на сервере?
sleep, добавь sleep
регулярки
поддрежку webcosket , дабы можно было-бы в тонком клиенте прогресс бар нарисовать.
rabbitmq
(8) pumbaE,
sleep:
Регулярки аналогично через perl/grep.
Вообще, есть мысль написать статью про вызов линуксовых команд из 1С. В простейшем варианте через ЗапуститьПриложение() с перенаправлением stdout во временный файл с последующим разгребанием этого файла средствами 1С. Но хочется ещё реализовать компоненту для работы без временного файла, т.е. вызывается команда и её stdout читается прямо в строку 1С (возможная опция — запись в stdin). В примитивном варианте это можно сделать в компоненте через popen(), в более продвинутом через pipe()/fork()/exec(). Собственно, и статья родилась когда решил попробовать реализовать эту простенькую задачку и начал компилить сырцы 1с. Впрочем, popen() чего-то не захотел тогда работать (fread() сразу же возвращал 0, а feof(), соответственно, 1).
WebSocket и RabbitMQ — а что с ними делать? )))
(7) например для управления Asterisk используя AMI, нужен клиент telnet.
Есть ROM-Asterisk-Native, но там закрытый код.
(10) servs, яhttp://xgu.ru/wiki/AMI там можно обойтись или встроенным телнет клиентом в связке с expect, или написать что надо на python (благо, биндинги, судя по всему, есть). А запускать опять же банально через ЗапуститьПриложение().
Пастернака не читалс Astetisk-ом не работал, но судя поЕсли есть конкретная задача, можем посмотреть варианты решения.
(10) servs, ROM-Asterisk-Native насколько я знаю виндовый, а для линукса есть только у мико(далеко не бесплатно+куча **рни в подарок)+ она работает через богопротивный AJAM.
(11)
Немного не понял))
ЗапуститьПриложение() не канает. Нужно слушать события по telnet’у, причем желательно асинхронное поступление событий в 1с.
Хотя может я просто Вас не понял)
(1) kostyaomsk, сколько вам можно писать «ХВАТИТЬ ПИСАТЬ, ПОЧТИ В КАЖДОМ СООБЩЕНИИ СВОЕЙ БЕЗПОЛЕЗНЫЙ КОММЕНТАРИЙ?????!!!!!», вы по другому не умете зарабатывать $m? Взрослый мужик, а хитрун еще тот. Стыдно!
(14) myr4ik07, во-первых, беСполезный, а во-вторых, для выяснения отношений есть ЛС, форум, обращение к модераторам и т.п.
Это касается и (3)
Надеюсь на Ваше понимание.
(13) vslimv, это скорее я не понял. Т.е. нужно открыть сокет, слушать его, а полученные данные передавать в 1С? Так? А кто и что будет в этот сокет писать/читать с другой стороны (со стороны клиента)?
(15)А че ему можно писать че попало, а мне нельзя?
А че это вы тут указываете, если:
я предлагаю вам воспользоваться вашим же советом.
(16) Все именно так.Со стороны сервера asterisk висит AMI(Asterisk Manager API). Будет отсылать тебе после авторизации, все события в текстовом виде. Более подробно о нем и на русскомтут .
Со стороны клиента ВК и события из нее)
В общем задача ее принимать текст из 1С и отправлять в AMI и наоборот из AMI в 1С. Сама ничего уметь не должна, разве что отправлять в 1С ошибку при подключении к сокету, если таковая имеется.
Проблема с Alert-ами заключалась в том, что в в include/AddInDefBase.h в прототипе метода ожидается WCHAR_T* (строка 2-хбайтовых символов), а передаётся wchar_t* (строка 4-хбайтовых символов; L»OK» — это 4-хбайтовые символы):
Поэтому нужно поменять
на