Циклический избыточный код (CRC32) и NativeAPI

p1c8crc.dll — внешняя подключаемая через NativeAPI компонента из которой можно получить контрольную сумму для строки и предназначена для проверки целостности данных.

Недавно озадачился получением CRC кода для строк табличной части и вот что из этого получилось. Работы по настоящей тематике проходили в несколько этапов.

Этап 1

Изучение теоретических основ расчета CRC. На этом этапепомогли статьи » Циклический избыточный код« и «Элементарное руководство
по CRCалгоритмам обнаружения ошибок»

Этап 2

Знакомство с NativeAPI для 1С8. Отличная, доходчивая и (главное) дополненая примерами статья «ВК NativeAPI на Delphi и FreePascal«

Этап 3

Оставим теорию и переходим к практике. На любимом Delphi была напишем и скомпилируем dll, которая экспортирует единственную функцию «РасчитатьCRC32». Ей передается единственный строковый параметр, а на выходе получается строка в виде hex.

В модуле проекта объявляем класс:  

TCRC32Class = class(TV8UserObject)
public
function crc32Func(RetValue: PV8Variant; Params: PV8ParamArray; const ParamCount: integer; var v8:TV8AddInDefBase): boolean;
end;

и его реализацию:

function TCRC32Class.crc32Func(RetValue: PV8Variant;
Params: PV8ParamArray;
const ParamCount: integer;
var v8:TV8AddInDefBase): boolean;
var
p: WideString;
res: string;
begin
try
p := V8AsWString(@Params[1]);
res := IntToHex(CRC32String(p),0);
V8SetWString(RetValue, res);
result := True;
except
on E : Exception do begin
res:='['+E.ClassName+'] '+E.Message;
V8SetWString(RetValue, res);
result := False;
end;
end;
end;

также в части инициализации библиотеки пишем вот такой код:

  with ClassRegList.RegisterClass(TCRC32Class, 'ExecExtention', 'TCRC32Class') do
begin
AddFunc('crc32Func', 'РасчитатьCRC32', @TCRC32Class.crc32Func, 1);
end;

Функция CRC32String реализована в модуле ucrc32.pas, а класс TV8UserObject описан и реализован в модуле v8napi.pas (см. ссылку во втором этапе). Об окончании этого этапа работ сигнализирует файл p1c8crc.dll.

Этап 4

Теперь осталось подключить внешнюю компоненту к конфигурации 1С8.2 и использовать ее. Для этого создадим общий модуль «ОбщийМодульCRC32». В нем напишем вот такой код:

Функция ИнициализироватьКомпонентуCRC32() Экспорт
Попытка
ПодключитьВнешнююКомпоненту("ОбщийМакет.p1c8crc", "CRC32Lib", AddInType.Native);
ОбъектВК = Новый("AddIn.CRC32Lib.ExecExtention");
Исключение
Сообщить("Ошибка создания объекта внешней компоненты AddIn.CRC32Lib.ExecExtention");
Возврат Ложь;
КонецПопытки;

Адрес = ПоместитьВоВременноеХранилище(ОбъектВК, Новый УникальныйИдентификатор);
ПараметрыСеанса.нсиКомпонентаCRC32 = Адрес;
Возврат Истина;
КонецФункции

Функция ПолучитьКомпонентуCRC32() Экспорт
Возврат ПолучитьИзВременногоХранилища(ПараметрыСеанса.нсиКомпонентаCRC32);
КонецФункции

В модуле сеанса проинициализируем компоненту. Для того чтобы вызвать внешнюю компоненту и проверить ее создадим обработку с табличной частью «ТЧ» (реквизиты: наименование, код и crc32) и команду «РасчитатьCRC». Код получился следующий:

&НаСервере
Процедура РасчитатьCRCСерверная()

ВК = ОбщийМодульCRC32.ПолучитьКомпонентуCRC32();
Для Каждого Стр Из Объект.ТЧ Цикл
врСтрока = Стр.Наименование+";"+Стр.Код+";";
Стр.CRC32 = ВК.РасчитатьCRC32(врСтрока);
КонецЦикла;

КонецПроцедуры


&НаКлиенте
Процедура РасчитатьCRC(Команда)
РасчитатьCRCСерверная();
КонецПроцедуры

P.S.

Чуть не забыл. В общих макетах нужно создать макет с двоичными данными и именем «p1c8crc». В нее загрузить полученный на этапе 3 файл p1c8crc.dll.

1 Comment

  1. gislink

    Пишется то «Рассчитать» 😉 Единственный метод, и тот с ошибкой написан.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *