Имя: Пароль:
1C
1С v8
Нужно перегнать функцию в dll. Как сделать внешнюю компоненту?
0 trim89
 
14.08.19
05:48
Доброго времени суток.

Есть функция на ~100 строк, нечёткий поиск. Так как 1с слишком медленно работает со строками, то есть идея перегнать её в вк native. Стал читать материал на инфостате, где описывается как всё легко и просто. Да вот как бы не так. Ничего не работает. Залез на ИТС, скачал шаблоны и примеры внешней компоненты. Открываю примеры visual studio 15, начинаю сборку, вываливается куча ошибок по коду, сборка не получается. Открываю visual studio 10, visual studio 12 - куча ошибок, но уже других. visual studio 13 - открыл, собрал, подключил в 1с, вызываю функцию иииии "Ошибка при вызове метода контекста (Петля)". Понятно, что дело в кодировке, но где конкретно понятия не имею. cpp файл в ANSI сохраняль, в 1251 сохраняль, руские буквы из кода удаляль, все пересобираль и ошибка не уходит, я не понимаю где и что ему не нравиться, уже нервов не хватает

Добрые люди, поможите советом. Что не так? куда тыкать для исправления? если есть исходники dll, которая РАБОТАЕТ БЕЗ БУБНА, буду премного благодарен.
1 Garykom
 
гуру
14.08.19
05:56
Какие ЯП кроме 1С знаешь?
2 trim89
 
14.08.19
06:00
Знаю - ничего, могу прочитать и понять что код делает - стандарт delphi, basic, c++. Из сред разработки только delphi
3 Garykom
 
гуру
14.08.19
06:03
http://catalog.mista.ru/public/81644/
и там еще другой вариант есть под дельфи, короче два шаблона разных знаю
4 trim89
 
14.08.19
06:03
функция, которую надо перегнать - простейшая. По сути там циклы, конкатенация и битовые операции. Моих знаний конкретно для переноса на другой язык должно хватить. Проблема именно в создании dll.
5 ДенисЧ
 
14.08.19
06:04
А если идти не на нимофстрат, а на ИТС, и взять там шаблон для ВК?
6 trim89
 
14.08.19
06:05
(5) 4 предложение и далее - описание что из этого вышло
7 Garykom
 
гуру
14.08.19
06:07
https://github.com/Zawullon/fpnativeapi короче поищи

Но лучше на C# делай.
А еще лучше поднимай внешний http сервис и юзай его из 1С.
8 Garykom
 
гуру
14.08.19
06:08
(4) Там с ВК куча проблем, начиная от кодировок до работы с памятью на C++ и прочих извратов с передачей объектов или хотя бы длинных строк.
9 trim89
 
14.08.19
06:08
(3) (7) Спасибо, почитаю
10 VS-1976
 
14.08.19
06:36
Если тебе нужен полнотекстовый поиск, то можно использовать https://yandex.ru/turbo?text=https%3A%2F%2Fru.wikipedia.org%2Fwiki%2FSphinx_(%25D0%25BF%25D0%25BE%25D0%25B8%25D1%2581%25D0%25BA%25D0%25BE%25D0%25B2%25D0%25B0%25D1%258F_%25D0%25BC%25D0%25B0%25D1%2588%25D0%25B8%25D0%25BD%25D0%25B0)

Ставится так же на windows
11 VS-1976
 
14.08.19
06:38
12 trim89
 
14.08.19
06:48
(10) Мне не это надо. Есть текст, нужно найти в нём строку с заранее заданным количеством ошибок. Больше всего подходит agrep, но он на linux =(
13 trim89
 
14.08.19
06:50
strmatch я не помню уже почему не подошёл
14 Garykom
 
гуру
14.08.19
07:18
15 ДенисЧ
 
14.08.19
07:19
(0) @Но лучше на C# делай. @
Не слушай (7) ..
16 ДенисЧ
 
14.08.19
07:20
(6) И да, могу продать резиновую киянку...
Ибо у меня, который на с++ последний раз писал в 1999м году - собрать шаблон с ИТС получилось со второго раза (первый раз не ту студию взял)
17 Garykom
 
гуру
14.08.19
07:23
(15) ВК на C# это самое простое в реализации, но NativeAPI не будет, только обычная COM ВК
18 Garykom
 
гуру
14.08.19
07:24
(4) >функция, которую надо перегнать - простейшая.

Дай функцию в студию плиз
19 trim89
 
14.08.19
07:27
(18) &НаСервере
функция АлгоритмНечеткогоПоиска(Текст,СтрокаПоиска) экспорт
    //алгоритм Bitap, модификация от Wu-Manber
    m = СтрДлина(Текст);
    n = СтрДлина(СтрокаПоиска);
    
    ФорматнаяСтрока = "ЧЦ="+формат(n,"ЧГ=0")+"; ЧН=; ЧВН=; ЧГ=0";
    U = новый Соответствие;
    для i = 1 по n цикл                  
        ключ = сред(СтрокаПоиска,i,1);
        БитовыйВектор = U.Получить(ключ);
        если БитовыйВектор = Неопределено тогда
            БитовыйВектор = формат(0,ФорматнаяСтрока);                  
        КонецЕсли;
        БитовыйВектор = лев(БитовыйВектор,i-1) + "1"+прав(БитовыйВектор,n-i);
        U.Вставить(ключ,БитовыйВектор);
    КонецЦикла;
    МассивНоваяПопытка = новый Массив(m);    
    МаксОшибка = макс(2,цел(СтрДлина(СтрокаПоиска)/10));
    Для Ошибка = 0 по МаксОшибка цикл
        M1 = формат(0,ФорматнаяСтрока);        
        МассивПредыдущаяПопытка = новый массив;
        Для каждого стр из МассивНоваяПопытка цикл
            МассивПредыдущаяПопытка.Добавить(стр);
        КонецЦикла;
        для j = 1 по m цикл              
            БитовыйВектор = U.Получить(сред(Текст,j,1));
            Если БитовыйВектор = Неопределено тогда
                БитовыйВектор = формат(0,ФорматнаяСтрока);
            КонецЕсли;
            УмножениеСВектором = ПобитовоеУмножение(СдвигВПраво(M1,n),БитовыйВектор,ФорматнаяСтрока);
            Если Ошибка = 0 тогда
                ПредыдущаяПопыткаj_1 = формат(0,ФорматнаяСтрока);    
            иначеЕсли j = 1 тогда
                ПредыдущаяПопыткаj_1 = формат(0,ФорматнаяСтрока);    
            иначе
                ПредыдущаяПопыткаj_1 = МассивПредыдущаяПопытка[j-2];                    
            КонецЕсли;
            
            Если Ошибка = 0 тогда
                ПредыдущаяПопыткаj = формат(0,ФорматнаяСтрока);    
            иначе
                ПредыдущаяПопыткаj = МассивПредыдущаяПопытка[j-1];                    
            КонецЕсли;
            
            вставкаM1 = ПобитовоеСложение(УмножениеСВектором,ПредыдущаяПопыткаj_1,ФорматнаяСтрока);
            УдалениеM1 = ПобитовоеСложение(УмножениеСВектором,СдвигВПраво(ПредыдущаяПопыткаj,n),ФорматнаяСтрока);
            ЗаменаM1 = ПобитовоеСложение(УмножениеСВектором,СдвигВПраво(ПредыдущаяПопыткаj_1,n),ФорматнаяСтрока);
            //результат = вставкаM1 или УдалениеM1 или ЗаменаM1
            M1 = ПобитовоеСложение(вставкаM1,УдалениеM1,ФорматнаяСтрока);
            M1 = ПобитовоеСложение(M1,ЗаменаM1,ФорматнаяСтрока);
            МассивНоваяПопытка[j-1] = M1;
            Если прав(M1,1)="1" тогда
                //нужно найти начальный символ
                //идет там где первые ошибка бит =1, останльные 0
                СтрокаДляСравнения = формат(0,"ЧЦ="+формат(Ошибка+1,"ЧГ=0")+"; ЧН=; ЧВН=; ЧГ=0") ;
                СтрокаДляСравнения = СтрЗаменить(СтрокаДляСравнения,"0","1");
                СтрокаДляСравнения = СтрокаДляСравнения + формат(0,"ЧЦ="+формат(n-Ошибка-1,"ЧГ=0")+"; ЧН=; ЧВН=; ЧГ=0");
                Для Инт = -(j-1) по 0 цикл                    
                    Если МассивНоваяПопытка[-Инт] = СтрокаДляСравнения тогда
                        Прервать;
                    КонецЕсли;
                КонецЦикла;
                возврат(новый Структура("Слово,позиция,ошибок",Сред(Текст,-Инт+1,j+Инт),-Инт+1,Ошибка));
                //возврат -Инт+1;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    возврат(новый Структура("Слово,позиция,ошибок","",0,0));
КонецФункции
20 trim89
 
14.08.19
07:27
(18) &НаСервере
функция ПобитовоеУмножение(Число1,Число2,ФорматнаяСтрока)
    возврат СтрЗаменить(СтрЗаменить(Формат(Число(Число1) + Число(Число2), ФорматнаяСтрока), "1", "0"), "2", "1")
КонецФункции

&НаСервере
функция ПобитовоеСложение(Число1,Число2,ФорматнаяСтрока)
    возврат СтрЗаменить(Формат(Число(Число1) + Число(Число2), ФорматнаяСтрока), "2", "1");    
КонецФункции

&НаСервере
функция СдвигВПраво(Число1,n)
    возврат "1" + лев(Число1,n-1);
КонецФункции
21 trim89
 
14.08.19
07:28
(14) это bitap алгоритм, с модификацией для нечеткого поиска
22 trim89
 
14.08.19
07:38
(16) Если получилось собрать сейчас, то киянка не нужна, помоги советом: что, куда и какой studio брать?
23 Фрэнки
 
14.08.19
08:32
имхо, если точно также сделать строковыми операциями на си или дельфи, то существенного ускорения не получится. Да еще и будут потери на передачу стека параметров туда-суда обратно
24 Фрэнки
 
14.08.19
08:33
кстати, в приведенном примере кода также видно причина к снижению производительности на передачу стека параметров туда-сюда
25 Фрэнки
 
14.08.19
08:36
т.е. низкая скорость обработки данных в таком подходе провоцируется составлением слишком мелких функций, которые вызываются слишком часто с передачей параметров и возвратом параметров.
26 ДенисЧ
 
14.08.19
08:54
(17) КОМ на шарпе писать - это извращение
27 Garykom
 
гуру
14.08.19
09:03
(22) Любой VS от 2008 до 2019
У меня в VS2017 С++ ВК вполне скомпилились после множества матов.

Но имхо на С++ писать это изврат редкостный, пока ничего проще Книга знаний: Написание внешних компонент для 1С на VB.NET и C# не придумано.
Ну или Книга знаний: Написание внешних компонент для 1С (Delphi)
28 trim89
 
14.08.19
09:07
(25) нет, основная проблема в побитовом умножении и сложении. конркетно преобразования из строки в число и обратно даёт низкую скорость
29 trim89
 
14.08.19
09:09
(25) через побитовые операции тоже работает не намного быстрее, да и при определённых размерах строк выдаёт ошибки.
30 trim89
 
14.08.19
09:32
(27) "после множества матов.", вот то-то и оно. Времени много уходит на такую ересь, тем более что я не знаю что там и как. Приходится забрасывать запросами гугл. Надоело уже.
31 Garykom
 
гуру
14.08.19
09:36
(30) Шаблон на дельфи/лазарус вполне рабочий и nativeapi и com, но только x86.
Для x86_64 надо допиливать, недавно тема была пока вроде не взлетело еще.
32 Garykom
 
гуру
14.08.19
09:41
Сам я начал пилить ВК на C++ к которой можно внешние DLL на чем угодно подрубать, у меня на Golang.
Оно даже в тестовом варианте вполне работает NativeAPI и x86/x86_64 причем Windows/Linux.
Но куча разных тонкостей что можно а что еще низзя.

Короче сделай свой алгоритму на чем угодно и запускай его из командной строки с параметрами из 1С ))
Это реально простейший вариант, причем параметры в виде xml или json файла на вход и результат на выход тоже xml или json.
А затем просто поднимается апача и cgi-bin ))
33 Кирпич
 
14.08.19
09:50
(31) Не трынди. Ничо там допиливать не надо. Всё исправлено лет пять назад. Допиливают те, кому лень скачать модуль заново.
34 kyvv
 
14.08.19
10:19
(0)Даже у меня все получилось, попробуйте https://www.youtube.com/watch?v=wMYuwhmz4jk
35 MM
 
14.08.19
10:32
(33) У меня вывелось куча предупреждений при компиляции x86_64, хотя и заработало. Так что не всё там гладко.
36 Garykom
 
гуру
14.08.19
10:42
(33) Ну значит не тот модуль качают )) Под дельфи/лазарус их два в паблике есть совершенно разных
37 trim89
 
14.08.19
10:42
(34) Компонента скомпилилась, она подключается, функция не вызывается
38 trim89
 
14.08.19
10:43
(34) В ролике сказано про локализацию. Попробую эту тему ещё покопать.
39 H A D G E H O G s
 
14.08.19
12:35
Я один нихрена не понял?

Глобальный контекст (Global context)
ПобитовыйСдвигВлево (BitwiseShiftLeft)
Синтаксис:

ПобитовыйСдвигВлево(<Число>, <Смещение>)
Параметры:

<Число> (обязательный)

Выполняет побитовый сдвиг двоичного представления числа на заданное количество битов влево.
40 H A D G E H O G s
 
14.08.19
12:35
Ну и e.t.c
41 H A D G E H O G s
 
14.08.19
12:38
Ну и
ПолучитьБуферДвоичныхДанныхИзСтроки
42 Злопчинский
 
14.08.19
13:53
(13) стрматч не дает поиск с заранее заданным количеством ошибок.
стрматч можно выставить границу поиска, типа похоже более чем на 90%
43 Garykom
 
гуру
14.08.19
13:55
(42) У стрматч отвратный алгоритм нечеткого сравнения, для фонетики больше подходит а не опечаток.
44 Фрэнки
 
14.08.19
19:30
(41) ну я тоже попытался отговорить его от освоения новых технологий - не был услышан
45 NorthWind
 
14.08.19
19:38
(7) веб-сервис чтобы строку обработать?
Это прикол такой?
46 Garykom
 
гуру
14.08.19
19:41
(45) Почему прикол то?
Со временем все к этому придет, очень универсально некоторыми минусами.

Можно и одну строку, а можно и много строк сразу передать и разом обработать и получить результат.
Причем откуда угодно и из чего угодно, никакой возни с установкой и подключением ВК.

А если наконец то добавить в 1с встроенный веб-сервер и передавать в запросе обратный адрес то совсем отлично будет и асинхронно.
47 Garykom
 
гуру
14.08.19
19:42
(46)+ Но раньше чем IPv6 будет нормально распространено ждать не стоит.
48 tesseract
 
14.08.19
22:32
(0) 1C имеет очень быстрый нечеткий поиск и операции со строками - ты просто не понимаешь, что делаешь.  native вообще работает с utf8/16 без проблем. Даже в примере.
49 trim89
 
15.08.19
02:58
(48) Пример функции пжлст. Что нибудь похожее для произвольного текста я не нашёл.
50 trim89
 
15.08.19
03:05
(44) (41) (39) Побитовый операции в 1с для этой задачи имеют свои ограничения в размере строк. Конкретнее, число должно быть не более  2^32-1. То есть могу искать строку не более 32 символов, что хрень. По скорости не сильно выигрываю. С помощью такой эмуляции битовых операций могу обрабатывать гораздо большие строки.
51 ado
 
15.08.19
06:13
А если тупо сделать консольное приложение и вызывать его через КомандаСистемы()?
Ввод/вывод через временные файлы.
Ну, это, конечно, если функция "толстая".
52 trim89
 
15.08.19
07:26
(51) лучше время потратить на dll. Сейчас через delphi делаю, проблем не возникает.
53 trim89
 
15.08.19
11:42
Написал. По тестам, dll быстрее от 2.5 раз. На коротких словах и текстах до 8 раз. Вот мысля появилась сделать через битовые операции, а ограничение размера паттерна обходить алгоритмом а-ля Бойера-Мура. Думаю, это ещё больше убыстрит.
54 H A D G E H O G s
 
15.08.19
11:43
(50) Ты прикалываешься чтоли?
55 H A D G E H O G s
 
15.08.19
11:47
Как ты в Дельфи побитово складываешь строки? В Дельфи ты можешь максимум 8 байтные UINT64 побитово складывать - это 4 символа за цикл. В 1С ты складываешь 4 байтные UINT - 2 символа за цикл. В чем проблема?
56 NorthWind
 
15.08.19
12:06
(46) на одной строке смысла нет, потому что оверхед по операциям будет огромным - вы в тысячу раз больше строковых операций сделаете при запаковке данных в хмл/джейсон, потом при передаче, потом при распаковке, потом то же самое при работе с результатом. На большом объеме текста смысла немножко больше, но не факт что здесь не станет узким местом сетевое взаимодействие.
По-моему, использование веб-сервисов в подобной ситуации имеет смысл только тогда, когда со строками делается какой-нибудь достаточно уникальный сервис. Скажем, перевод с одного языка на другой близкий к естественному, или какое-то еще преобразование по правилам языка, которое затруднительно сделать без гигантской базы данных и искусственного интеллекта.
57 Volodja
 
15.08.19
12:48
58 Garykom
 
гуру
15.08.19
13:07
(56) Нельзя спорить что ВК конечно же быстрее, и когда надо много запросов строк в цикле без нее никак.
Или когда требования к скорости получения ответа жесткие.

Если же таких требований нет или надо разом много строк, да еще и клиент убогий (мобильный или браузер) то тут веб-серверная компонента сильно лучше.
59 trim89
 
15.08.19
14:03
(57) это метод n грамм, он, мягко говоря, не точный.
60 trim89
 
15.08.19
14:07
(55) а причем тут побитово складывать строки? Фишка данного алгоритма создание битовых векторов, которые потом складываются и умножаются. Ограничение в 1с 32 бита, то есть подстрока поиска макс 32 символа.
61 MetaDon
 
15.08.19
14:25
строки преобразовать в биты; а далее
Побитовые операции в 1С
62 H A D G E H O G s
 
15.08.19
14:31
(60) Можно пример на Дельфи по сложению битового вектора?
63 trim89
 
15.08.19
15:01
(62) неа, я пока не сделал и даже не разбирался.
64 trim89
 
20.08.19
04:50
Реализовал метод с битами в 1с и в dll. Разница во времени - несколько порядков. Конкретнее.

текст = "Текст = ""Мы дали общее описание того, как будут использоваться массивы сдвигов и прыжков. Массив сдвигов содержит величины, на которые может быть"";     
     |    рез = НечеткийПоиск2( Текст,СтрокаПоиск, Кэш,ОбъектВК);
     |    Текст = Текст + "" сдвинут образец при несовпадении очередного символа. В массиве прыжков содержатся величины, на которые можно сдвинуть образец, чтобы совместить ранее"";
     |    рез = НечеткийПоиск2( Текст,СтрокаПоиск, Кэш,ОбъектВК);
     |    Текст = Текст + "" совпавшие символы с вновь совпадающими символами строки. При несовпадении очередного символа образца с очередным символом текста может осуществиться"";
     |    рез = НечеткийПоиск2( Текст,СтрокаПоиск, Кэш,ОбъектВК);
     |    Текст = Текст + "" несколько возможностей. Сдвиг в массиве сдвигов может превышать сдвиг в массиве прыжков, а может быть и наоборот. (Совпадение этих величин - простейшая возможная ситуация.)"";
     |    рез = НечеткийПоиск2( Текст,СтрокаПоиск, Кэш,ОбъектВК );
     |    Текст = Текст + "" О чем говорят эти возможности? Если элемент массива сдвигов больше, то это означает, что несовпадающий символ оказывается """"ближе"""" к началу,"";
     |    рез = НечеткийПоиск2( Текст,СтрокаПоиск, Кэш,ОбъектВК );
     |    Текст = Текст + ""     чем повторно появляющиеся завершающие символы строки. Если элемент массива прыжков больше, то повторное появление завершающих символов строки начинается ближе"";
     |    рез = НечеткийПоиск2( Текст,СтрокаПоиск, Кэш,ОбъектВК );
     |    Текст = Текст + ""     к началу образца, чем несовпадающий символ. В обоих случаях нам следует пользоваться большим из двух сдвигов, поскольку меньший сдвиг неизбежно опять приводит к"";
     |    рез = НечеткийПоиск2( Текст,СтрокаПоиск, Кэш,ОбъектВК );
     |    Текст = Текст + ""     несовпадению из-за того, что мы знаем о втором значении. Так, например, если значение сдвига равно 2, а значение прыжка 4, то сдвиг на два символа не позволит найти"";
     |    рез = НечеткийПоиск2( Текст,СтрокаПоиск, Кэш,ОбъектВК );
     |    Текст = Текст + ""         соответствие образцу: несовпадающий символ все равно окажется невыровненным. Однако, если сдвинуть на четыре символа, то под ранее несовпадающим символом окажется"";
     |    рез = НечеткийПоиск2( Текст,СтрокаПоиск, Кэш,ОбъектВК );
     |    Текст = Текст + ""         подходящий символ образца, и при этом сохраняется возможность того, что завершающие символы образца будут совпадать с новыми соответствующими символами текста."";
     |    рез = НечеткийПоиск2( Текст,СтрокаПоиск, Кэш,ОбъектВК );
     |    Текст = Текст + ""     Поскольку речь идет только о большем из двух значений, алгоритм имеет следующий вид: Счут на оплату"";
     |    рез = НечеткийПоиск2( Текст,СтрокаПоиск, Кэш,ОбъектВК ";


Число знаков тут больше 2 тысяч, с пробелами ~2500. Ищу 50 раз циклом 2 строки, короткую и длинную. Соответсвенно "Счfт на оjлату" и "Текст = Текст + ""     Поскольку речь идет только о бfльшем из двух значений, алгоритм имеnт следующий вид: Счут на оплату""". В каждой из этих строк по 2 ошибки.

В функции на 1с цикл 50 раз для короткой строки отрабатывает 17,675345, длинная - 6,009056
В dll, короткая - 0,020312, длинная - 0,019405.

В общем, своей работой я доволен =) Всем спасибо.
Программист всегда исправляет последнюю ошибку.