ВК NativeAPI на Delphi и FreePascal

Опубликовал Александр Соломатин (v77) в раздел Программирование - Внешние компоненты

1CNativeLib - бесплатная библиотека Delphi для создания внешних компонент (ВК) 1С по технологии Native API.
Новая версия.
16.12.2015 Исправлена ошибка: поиск свойств и методов ВК выполнялся с учетом регистра букв.
06.10.2015 Исправлена ошибка: сообщение "некорректная работа компоненты с памятью"

 

1CNativeLib - библиотека Delphi для создания внешних компонент (ВК) 1С по технологии Native API. Библиотека легка в использовании и позволяет заниматься непосредственно функционалом ВК, не отвлекаясь на соблюдение инструкций, предоставленных фирмой 1С.

 

Для того, чтобы создать ВК с помощью 1CNativeLib, достаточно создать проект DLL, написать класс с реализацией функционала вашей ВК и зарегистрировать этот класс при загрузке dll. Минимальный проект DLL с реализацией класса с одним методом выглядит так:

 

//-----------------------------------------------------------------

 

library MiniVK;

 

uses

SysUtils, v8napi;

 

type

TMyClass = class(TV8UserObject)

function Hello(RetValue: PV8Variant; Params: PV8ParamArray;

const ParamCount: integer): boolean;

end;

 

{ TMyClass }

 

function TMyClass.Hello(RetValue: PV8Variant; Params: PV8ParamArray;

const ParamCount: integer): boolean;

begin

V8SetWString(RetValue,'Привет из Delphi!'); //устанавливаем результат функции

result := True; //Устанавливаем флаг, что функция завершилась успешно

end;

 

begin

with ClassRegList.RegisterClass(TMyClass, 'MySuperExtention', 'TMyClass') do

begin

AddFunc('Hello', 'Привет', @TMyClass.Hello, 0); //регистрируем функцию

end;

end.

 

//-----------------------------------------------------------------

 

Всё необходимое содержится в одном модуле v8napi.pas. В прилагаемом архиве сам модуль, пример, более подробное описание и шаблон для нового проекта.

 

Скачать файлы

Наименование Файл Версия Размер
1CNativeLib.zip
.zip 44,87Kb
17.10.12
252
.zip 44,87Kb 252 Скачать
Вариант для FreePascal (Lazarus)
.zip 10,42Kb
16.10.12
96
.zip 10,42Kb 96 Скачать
v8napi.pas от 16.12.2015
.pas 39,71Kb
16.12.15
58
.pas 39,71Kb 58 Скачать

См. также

Комментарии
1. Ярослав Тарарака (slaviksoft) 68 17.02.11 16:11 Сейчас в теме
2. Ярослав Тарарака (slaviksoft) 68 18.02.11 09:55 Сейчас в теме
меня интересует - этот модуль на delphi Вы сами писали или это от 1С?
3. Александр Соломатин (v77) 131 18.02.11 11:11 Сейчас в теме
Сами конечно. Какой смысл выкладывать модуль от 1с?
4. Сергей (sipoju) 18.02.11 15:22 Сейчас в теме
Извините что не в тему, но мне тяжеловато работать с Делфями :cry:
Есть ли такое же только на С++? (Borland Builder или Visual C++)
5. Александр Соломатин (v77) 131 18.02.11 15:33 Сейчас в теме
На ИТС есть документация и примеры на Си++
6. Андрей Акулов (DrAku1a) 1199 21.02.11 04:20 Сейчас в теме
Возможно ли использование на FPC+Lazarus?
И еще - было бы неплохо и для v77 аналогичный ВК-класс сделать.
7. Александр Соломатин (v77) 131 21.02.11 08:22 Сейчас в теме
DrAku1a пишет:

Возможно ли использование ?
И еще - было бы неплохо и для v77 аналогичный ВК-класс сделать.

Для FPC+Lazarus надо допиливать. Сходу не заработало, но заработает.
Для v77 можно сделать, но вроде как уже и так хватает.
8. Юрий Ульянов (i-man) 15.05.11 21:31 Сейчас в теме
есть возможность как то передавать не простые данные в ВК, а ссылки на элементы справочников или документов и уже внутри ВК с этими элементами работать?
если можно примерчик небольшой

спасибо заранее
9. Александр Соломатин (v77) 131 17.05.11 11:44 Сейчас в теме
Нету такой возмоности. В NativeAPI такое не предусмотрено.
10. Ийон Тихий (cool.vlad4) 41 17.05.11 11:50 Сейчас в теме
(8) зачем? для этого 1С есть...
11. romix (romix) 593 01.08.11 11:14 Сейчас в теме
Проверил однако работает! Спасибо!
12. romix (romix) 593 01.08.11 18:15 Сейчас в теме
Компонента на основе этой с полезным функционалом, которого отчасти не хватало в 1С 8.2 http://infostart.ru/public/88060/ (запуск процесса, переключение раскладки и др.).
13. Вадим Скакун (UncleVader) 125 01.08.11 19:33 Сейчас в теме
(9) Я так понимаю что не предусмотрен возврат и ссылок на таблицу значений или на какую другую коллекцию значений?
14. johnrex 16.09.11 07:18 Сейчас в теме
Скажите, пожалуйста, возможно ли с использованием NativeApi организовать поток (Delphi), который будет независимо выполнять определенные действия, и генерить в нужных ситуациях внешнее событие в 1С 8. В моем случае нужно опрашивать весы подключенные к com порту с периодичностью хотя бы раз в секунду и если они подключены при изменении веса отсылать данные в 1С. Обработчик ожидания не устраивает, так как 1С работает однопоточно и очень сильно висит при опросе com порта.
15. Сергей Мурзинов (Sergey_Murzinov) 04.10.11 22:58 Сейчас в теме
Спасиюо, толковая работа
16. zag2art (zag2art) 21.10.11 19:51 Сейчас в теме
17. zag2art (zag2art) 23.10.11 19:19 Сейчас в теме
(9) тот же вопрос, что и в (13) ответьте пожалуйста.
18. Александр Соломатин (v77) 131 23.10.11 22:33 Сейчас в теме
19. Александр Соломатин (v77) 131 23.10.11 22:35 Сейчас в теме
(13) Можно передавать только простые типы данных и вернуть из ВК двоичные данные. Вроде всё пока. Остальное 1С блокирует.
20. Рамиль (mur611) 25.10.11 14:05 Сейчас в теме
Здравствуйте,
Пробовал по примеру писать NativeAPI компоненту, но почему то не воспринимает функции, пишет "Поле объекта не обнаружено (Hello)". Или v8napi.pas от http://infostart.ru/public/88060/ не подходит для самого простого примера. А вообще стоит задача написать внешнюю компоненту для общения с COM портом. и используя ваш пример можно написать данную ВК?
21. Рамиль (mur611) 25.10.11 14:09 Сейчас в теме
есть конечно примеры на CPP, но времени разбирать с Visual большого нет.
22. Александр Соломатин (v77) 131 26.10.11 12:01 Сейчас в теме
(20) видимо где то чего то неправильно понаписал. У всех работает нормально, жалоб не было.
23. Рамиль (mur611) 03.11.11 12:52 Сейчас в теме
есть вопрос. Заключается он в том, что в ВК на технологии СОМ обработка ошибок во ВК производилась функцией RaiseLastOSError и все работает ОК, а вот теперь вроде сделал на Native API, и при вызове данной функции ВК, 1Ска закрывается (вылетает). какие методы есть решения? не подскажете.
24. Александр Соломатин (v77) 131 03.11.11 13:32 Сейчас в теме
(23) mur611,
V8.AddError(wcode: word; const source: PWideChar;
const descr: PWideChar;
scode: integer): boolean;

см. документацию от 1С
25. igor (igor_kav) 95 26.03.12 10:47 Сейчас в теме
есть вопрос, как вернуть массив? входные параметры функции - число, строка, а вот вернуть функция должна массив или olevariant, каа быть?
26. Spi1y (Spi1y) 26.03.12 11:19 Сейчас в теме
(25) igor_kav, только генерировать строку с внутренним представлением любой коллекции (массив, структура, список значений, и т.д.), а в 1С уже преобразуешь с помощью ЗначениеИзСтрокиВнутр(). К сожалению, я не смог найти ни одного внятного описания структуры внутреннего представления ТаблицыЗначений, а по всем остальным коллекциям формат довольно простой.
Сам на основе данного шаблона делал компоненту для внутреннего использования, с возвратом из функции массива. Если нужно, напиши, кину пример кода.
27. Spi1y (Spi1y) 26.03.12 11:26 Сейчас в теме
Вот как раз и пример со структурой, у массива формат еще проще:

  pwi.cbSize := SizeOf(pwi);
  if WindowHandle <> 0 then begin
    Result := GetWindowInfo(WindowHandle, pwi);
    if Result then begin
      ResultString := '{"#",4238019d-7e49-4fc9-91db-b6b951d5cf8e,{4,{{"S","Лево"},{"N",';
      ResultString := ResultString + IntToStr(pwi.rcWindow.Left) + '}},{{"S","Верх"},{"N",';
      ResultString := ResultString + IntToStr(pwi.rcWindow.Top) + '}},{{"S","Ширина"},{"N",';
      ResultString := ResultString + IntToStr(pwi.rcWindow.Right - pwi.rcWindow.Left) + '}},{{"S","Высота"},{"N",';
      ResultString := ResultString + IntToStr(pwi.rcWindow.Bottom - pwi.rcWindow.Top) + '}}}}';
    end else
      ResultString := '{"#",4238019d-7e49-4fc9-91db-b6b951d5cf8e,{0}}';
    end;
    V8SetWString(RetValue, ResultString);
...Показать Скрыть
28. igor (igor_kav) 95 26.03.12 11:28 Сейчас в теме
было бы здорово готовый код глянуть. скиньте, пожалуйста, на мыло igor_kav@mail.ru
спасибо!
29. igor (igor_kav) 95 26.03.12 11:29 Сейчас в теме
спасибо! пока писал коммент, Вы уже выложили.
30. igor (igor_kav) 95 26.03.12 11:36 Сейчас в теме
а как быть с многомерным массивом?
31. Spi1y (Spi1y) 26.03.12 12:10 Сейчас в теме
Кхм, понятия не имею. Честно говоря, ни разу за всю практику не сталкивался с необходимостью использования многомерных массивов. Но, если размышлять логически, то сам формат представления для массива таков:

{"#",4238019d-7e49-4fc9-91db-b6b951d5cf8e,{КоличествоЭлементов,{ОписаниеКлюча1, ОписаниеЗначения1}, ... , {ОписаниеКлючаN, ОписаниеЗначенияN}}}

где ОписаниеКлючаN и ОписаниеЗначенияN:
{ОписаниеТипа,Значение}


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

Но надо проверять, конечно. Попозже гляну.
32. Spi1y (Spi1y) 26.03.12 12:17 Сейчас в теме
Извиняюсь, как говориться, поспешишь - людей насмешишь. В предыдущем сообщении спутал понятия массивы и структуры. Массив разобрал, еще проще выходит:

{"#",51e7a0d2-530b-11d4-b98a-008048da3034,{КоличествоЭлементов,{ОписаниеЗначения1}, ... , {ОписаниеЗначенияN}}}

И действительно, для вложенных массивов достаточно в описание значения вместо строки {ОписаниеТипа,Значение} передать строку {ОписаниеМассива}, сформированную аналогично.
33. igor (igor_kav) 95 26.03.12 16:58 Сейчас в теме
Spi1y, Спасибо! ОЧЕНЬ помогли!
34. Spi1y (Spi1y) 26.03.12 17:25 Сейчас в теме
35. igor (igor_kav) 95 30.03.12 16:55 Сейчас в теме
Пару функций удалось сделать и использовать в 1С, но написал третью функцию в dll... при попытке использования в 1с именно этой третьей функции, 1с вылетает с ошибкой "Программа 1Сv8 не работает Возникшая проблема привела к прекращению работы программы. бла-бла". Самое интересное, что для тестирования создал проект VLC на delphi, поместил в него код функции. В VLC-проекте ФУНКЦИЯ РАБОТАЕТ!

Какие есть варианты решения?
36. Александр Соломатин (v77) 131 30.03.12 17:17 Сейчас в теме
37. igor (igor_kav) 95 30.03.12 17:24 Сейчас в теме

library aukro_soap;

uses
  SysUtils,
  Classes,
  DateUtils,
  InvokeRegistry,
  Rio,
  SOAPHTTPClient,
  v8napi,
  uploader;

{$R *.res}

type

TMyClass = class(TV8UserObject)
  private
     RIO           : THTTPRIO;
     country_id    : Integer;
     local_version : Int64;
  public
    function doLogin(RetValue: PV8Variant; Params: PV8ParamArray; const ParamCount: integer): boolean;
    function getMyData(RetValue: PV8Variant; Params: PV8ParamArray; const ParamCount: integer): boolean;
    function getCatsList(RetValue: PV8Variant; Params: PV8ParamArray; const ParamCount: integer): boolean;
    constructor Create; override;
end;

{ TMyClass }

function TMyClass.doLogin(RetValue: PV8Variant; Params: PV8ParamArray; const ParamCount: integer): boolean;
var
  user_login          : string;
  user_password       : string;
  webapi_key          : string;
  info                : string;
  ver_key             : Int64;
  session_handle_part : string;
  user_id             : Int64;
  server_time         : Int64;
begin
  // получаем параметры функции
  user_login    := V8AsAString(@Params[1]);
  user_password := V8AsAString(@Params[2]);
  webapi_key    := V8AsAString(@Params[3]);

  try
    (RIO as AllegroWebApiPortType).doQuerySysStatus(local_version, country_id, webapi_key, info, ver_key);
    (RIO as AllegroWebApiPortType).doLogin(user_login, user_password, country_id, webapi_key, ver_key, session_handle_part, user_id, server_time);

    V8SetWString(RetValue, session_handle_part); // устанавливаем результат функции
    result := True;
  except
    result := False;
  end;
end;

// ФУНКЦИЯ НЕ РАБОТАЕТ !!! СКОРЕЕ ВСЕГО УТЕЧКА ПАМЯТИ ИЗ-ЗА ИСПОЛЬЗОВАНИЯ STRING
function TMyClass.getMyData(RetValue: PV8Variant; Params: PV8ParamArray; const ParamCount: integer): boolean;
var
  session_handle_part    : string;
  user_data              : UserDataStruct;
  invoice_data           : InvoiceDataStruct;
  company_extra_data     : CompanyExtraDataStruct;
  company_second_address : CompanySecondAddressStruct;
  pharmacy_data          : PharmacyDataStruct;
  alcohol_data           : AlcoholDataStruct;
  related_persons        : RelatedPersonsStruct;
  ResultString           : WideString;
begin
  // получаем параметры функции
  session_handle_part    := V8AsAString(@Params[1]);
  // инициализируем переменные
  user_data              := UserDataStruct.Create;
  invoice_data           := InvoiceDataStruct.Create;
  company_extra_data     := CompanyExtraDataStruct.Create;
  company_second_address := CompanySecondAddressStruct.Create;
  pharmacy_data          := PharmacyDataStruct.Create;
  alcohol_data           := AlcoholDataStruct.Create;
  related_persons        := RelatedPersonsStruct.Create;

  try
    (RIO as AllegroWebApiPortType).doGetMyData(session_handle_part, user_data, invoice_data, company_extra_data,
                                               company_second_address, pharmacy_data, alcohol_data, related_persons);

    ResultString := '{"#",4238019d-7e49-4fc9-91db-b6b951d5cf8e,{22,';
    ResultString := ResultString + '{{"S","user_id"},{"N",'+IntToStr(user_data.user_id)+'}},';
    ResultString := ResultString + '{{"S","user_login"},{"S","'+user_data.user_login+'"}},';
    ResultString := ResultString + '{{"S","user_rating"},{"N",'+IntToStr(user_data.user_rating)+'}},';
    ResultString := ResultString + '{{"S","user_first_name"},{"S","'+user_data.user_first_name+'"}},';
    ResultString := ResultString + '{{"S","user_last_name"},{"S","'+user_data.user_last_name+'"}},';
    ResultString := ResultString + '{{"S","user_maiden_name"},{"S","'+user_data.user_maiden_name+'"}},';
    ResultString := ResultString + '{{"S","user_company"},{"S","'+user_data.user_company+'"}},';
    ResultString := ResultString + '{{"S","user_country_id"},{"N",'+IntToStr(user_data.user_country_id)+'}},';
    ResultString := ResultString + '{{"S","user_state_id"},{"N",'+IntToStr(user_data.user_state_id)+'}},';
    ResultString := ResultString + '{{"S","user_postcode"},{"S","'+user_data.user_postcode+'"}},';
    ResultString := ResultString + '{{"S","user_city"},{"S","'+user_data.user_city+'"}},';
    ResultString := ResultString + '{{"S","user_address"},{"S","'+user_data.user_address+'"}},';
    ResultString := ResultString + '{{"S","user_email"},{"S","'+user_data.user_email+'"}},';
    ResultString := ResultString + '{{"S","user_phone"},{"S","'+user_data.user_phone+'"}},';
    ResultString := ResultString + '{{"S","user_phone2"},{"S","'+user_data.user_phone2+'"}},';
    ResultString := ResultString + '{{"S","user_ss_status"},{"N",'+IntToStr(user_data.user_ss_status)+'}},';
    ResultString := ResultString + '{{"S","site_country_id"},{"N",'+IntToStr(user_data.site_country_id)+'}},';
    ResultString := ResultString + '{{"S","user_junior_status"},{"N",'+IntToStr(user_data.user_junior_status)+'}},';
    ResultString := ResultString + '{{"S","user_birth_date"},{"N",'+IntToStr(user_data.user_birth_date)+'}},';
    ResultString := ResultString + '{{"S","user_has_shop"},{"N",'+IntToStr(user_data.user_has_shop)+'}},';
    ResultString := ResultString + '{{"S","user_company_icon"},{"N",'+IntToStr(user_data.user_company_icon)+'}},';
    ResultString := ResultString + '{{"S","user_is_allegro_standard"},{"N",'+IntToStr(user_data.user_is_allegro_standard)+'}}}}';

    V8SetWString(RetValue, ResultString); // устанавливаем результат функции
    result := True;
  except
    result := False;
  end;
end;

function TMyClass.getCatsList(RetValue: PV8Variant; Params: PV8ParamArray; const ParamCount: integer): boolean;
var
  webapi_key    : string;
  cats_list     : ArrayOfCats;
  ver_key       : Int64;
  ver_str       : string;
  CurrCats      : CatInfoType;
  ResultString  : WideString;
begin
  // получаем параметры функции
  webapi_key    := V8AsAString(@Params[1]);
  // инициализируем переменные
  CurrCats      := CatInfoType.Create;

  try
    (RIO as AllegroWebApiPortType).doGetCatsData(country_id, local_version, webapi_key, cats_list, ver_key, ver_str);

    // формируем массив из структур для 1С, затем в 1С необходимо использовать функцию "ЗначениеИзСтрокиВнутр()"
    ResultString := '{"#",51e7a0d2-530b-11d4-b98a-008048da3034,{'+IntToStr(Length(cats_list));
    for CurrCats in cats_list do
    begin
      ResultString := ResultString + ',{"#",4238019d-7e49-4fc9-91db-b6b951d5cf8e,{4,{{"S","cat_id"},{"S","'+IntToStr(CurrCats.cat_id)+'"}},';
      ResultString := ResultString + '{{"S","cat_name"},{"S","'+CurrCats.cat_name+'"}},';
      ResultString := ResultString + '{{"S","cat_parent"},{"S","'+IntToStr(CurrCats.cat_parent)+'"}},';
      ResultString := ResultString + '{{"S","cat_position"},{"S","'+IntToStr(CurrCats.cat_position)+'"}}}}';
    end;
    ResultString := ResultString + '}}';

    V8SetWString(RetValue, ResultString); // устанавливаем результат функции
    result := True;
  except
    result := False;
  end;
end;

constructor TMyClass.Create;
begin
  RIO := THTTPRIO.Create(nil);
  RIO.WSDLLocation := 'http://webapi.allegro.pl/uploader.php?wsdl';
  RIO.Service      := 'AllegroWebApiService';
  RIO.Port         := 'AllegroWebApiPort';

  country_id       := 209; // 209 - Украина; 228 - Neverland (webapi) для тестового сервиса http://testwebapi.pl
  local_version    := 1;
end;


begin

  with ClassRegList.RegisterClass(TMyClass, 'MySuperExtention', 'TMyClass') do
  begin
    // регистрируем функции
    AddFunc('doLogin',         'Авторизироваться',        @TMyClass.doLogin,         3);
    AddFunc('getMyData',       'ПолучитьМоиДанные',       @TMyClass.getMyData,       1);
    AddFunc('getCatsList',     'ПолучитьСписокКатегорий', @TMyClass.getCatsList,     1);
  end;

end.
...Показать Скрыть
38. igor (igor_kav) 95 30.03.12 18:10 Сейчас в теме
поставил исключение в процедуре _CallAsFunc и получил ошибку:

Внешняя компонента : Invalid pointer operation.
Ошибка! {Форма.Форма.Форма(473)}: Ошибка при вызове метода контекста (ПолучитьМоиДанные): Ошибка внешней компоненты
39. Александр Соломатин (v77) 131 30.03.12 18:35 Сейчас в теме
(38) ну вроде всё правильно. смотри в отладчике.
40. igor (igor_kav) 95 30.03.12 18:40 Сейчас в теме
41. igor (igor_kav) 95 30.03.12 18:53 Сейчас в теме
Прочитал, что СКОРЕЕ ВСЕГО УТЕЧКА ПАМЯТИ ИЗ-ЗА ИСПОЛЬЗОВАНИЯ STRING, но как решить ума не приложу...

Кто сталкивался, ПОМОГИТЕ!
42. Александр Соломатин (v77) 131 30.03.12 23:58 Сейчас в теме
43. igor (igor_kav) 95 31.03.12 01:25 Сейчас в теме
выдает ошибку External exception C000001D на строке:
(RIO as AllegroWebApiPortType).doGetMyData(session_handle_part, user_data, invoice_data, company_extra_data,
                                             company_second_address, pharmacy_data, alcohol_data, related_persons);


Но только в DLL, в EXE все нормально работает. В чем же все-таки причина?
44. igor (igor_kav) 95 31.03.12 15:01 Сейчас в теме
Можно ли передать функции параметр типа ТаблицаЗначений или XDTO пакет и как его потом в delphi разобрать?
45. Александр Соломатин (v77) 131 31.03.12 16:39 Сейчас в теме
(43) причина в ошибке. надо смотреть в отладчике. вышли мне исходники, я гляну. у тебя delphi 7?
46. igor (igor_kav) 95 31.03.12 16:44 Сейчас в теме
(45) спасибо! :) ошибку нашел! все, как всегда, было банально просто. RIO не освобождал.
Спасибо за проделанную работу, очень нужную вещь ВК NativeAPI на Delphi создали.
47. Александр Соломатин (v77) 131 31.03.12 16:50 Сейчас в теме
48. Andrew V (0xe0) 05.07.12 14:04 Сейчас в теме
Александр, из компоненты (*в вашей реализации) есть возможность обращаться к методам интерфейса 1С?
49. Сергей Вн (EmpireSer) 10.08.12 01:34 Сейчас в теме
Объясните мне - зачем нужна структура "ТV8ObjectRec" ?
50. Владислав Ярославлев (vladon) 18 25.09.12 15:46 Сейчас в теме
На сервере x64 не работает, к сожалению. Ковыряю-ковыряю код, не пойму, в чём дело.
51. Александр Соломатин (v77) 131 26.09.12 08:34 Сейчас в теме
Я на 64 не пробовал. Может так заработает(см. прикрепленный файл)
Прикрепленные файлы:
v8napi.zip
52. Владислав Ярославлев (vladon) 18 26.09.12 15:22 Сейчас в теме
(51) v77, это из оригинальных исходников от Александра Соломатина? Нет, тоже не получается.
53. Александр Соломатин (v77) 131 26.09.12 15:55 Сейчас в теме
Ну у меня нету сервера 64. пока ничем не могу помочь.
54. Александр Соломатин (v77) 131 26.09.12 15:56 Сейчас в теме
(52) vladon, а на клиенте 64 работает?
55. Александр Соломатин (v77) 131 26.09.12 15:59 Сейчас в теме
(52) vladon, а как не работает? в чем компилировалось?
56. Владислав Ярославлев (vladon) 18 26.09.12 16:01 Сейчас в теме
(54) v77, клиента 64 же не существует.

компилировалось Delphi XE2 и Delphi XE3.
57. Александр Соломатин (v77) 131 26.09.12 21:22 Сейчас в теме
(56) vladon, ну и как не работает то. в чем это не работает проявляется?
58. Владислав Ярославлев (vladon) 18 26.09.12 22:34 Сейчас в теме
(57) v77, вот здесь лежит архив со всеми исходниками: http://narod.ru/disk/61615376001.5ca45c99a6ebdc7d919aa57124f0aa7b/SocketNative.zip.html

в каталоге 1С есть .dt-шник, это база, где в общий макет залиты dll-ки с манифестом в зипе, dll-ки откомпилены delphi xe3, в любом случае все исходники там же

и есть обработка, которая запускает подключение компоненты на сервере

так вот, на 32-бит сервере компонента подключается - всё нормально отрабатывает
на 64-бит сервере при нажатии кнопки "Подключить компоненту" сервер долго-долго думает, а потом клиент вылетает с сообщением, что сервер принудительно закрыл подключение.

в любом случае, если есть возможность, попробуйте сами.
59. Александр Соломатин (v77) 131 29.09.12 23:56 Сейчас в теме
(58) vladon, попробуй такой вариант. у меня вроде работает. на сервере не проверял(нету у меня). проверял тестовой программой, которая загружает dll и читает список методов и свойств ВК. старая твоя ВК не грузилась, теперь стала грузиться. в архиве вариант модуля v8napi.pas. отпишись заработало или нет.
60. Александр Соломатин (v77) 131 29.09.12 23:57 Сейчас в теме
61. Владислав Ярославлев (vladon) 18 01.10.12 08:50 Сейчас в теме
(60) v77, огромное спасибо, работает.
62. andrewks 1195 20.10.12 21:36 Сейчас в теме
какова лицензия на исходный код? возможно ли его использование в проектах под лицензией GPL v2/3?
63. Александр Соломатин (v77) 131 22.10.12 10:19 Сейчас в теме
Да используйте где хотите.
64. andrewks 1195 23.10.12 09:14 Сейчас в теме
(63) v77, не сочтите за наглость, но, так сказать, во избежание возможных недоразумений, можно при следующем обновлении в программных модулях указать тип лицензии на исходный код? например, Apache 2.0 (наиболее предпочтительная и либеральная), X11, или Modified BSD (неограниченное использование). или двойную лицензию GPL v2 и GPL v3 (на выбор пользователя).

хотим тут один небольшой проектик замутить на базе модуля для FreePascal под лицензией GPL v2, в целях экономии времени на рутину хотим использовать Ваш модуль ;-)

спасибо.
65. 11 22 (eoego1) 20.11.12 17:55 Сейчас в теме
Мегаценная вещь, спасибо автору большое! Но возник вопрос, мне очень нужно сделать так, чтобы во время работы какой либо одной функции вызванной по nativeapi из 1С, произошла передача данных (к примеру установка свойства формы или генерация внешенего события с передачей данных в 1С). Например:

//процедура вызываемая из 1С
function TMyClass.SleepFunc(RetValue: PV8Variant; Params: PV8ParamArray; const ParamCount: integer; var v8:TV8AddInDefBase): boolean;
var
ms: Integer;
begin
ms := V8AsInt(@Params[1]); // к примеру 100.000
//тут хочу вызвать исключение в 1С и передать в него строку "Привет я пошел спать!" или как-то иначе
sleep(ms);
//допустим тут еще раз хочу вызвать исключение
//или установить свойство заголовка на форме или переменной модуля 1С. "Привет я проснулся!"
result := True; //завершается вызванная функция
end;
После некоторых исследований, было установлено, что к примеру если вызвать во время работы функции sleep (или любой другой) функцию, например, вызова внешнего события, то оно генерируется не в то время, где я вызываю ExternalEvent, а только по выходу из основной функции. То есть у меня никак не получается передавать в 1С, например строку промежуточного результата работы функции во время ее работы. Все уходит в 1С только по выходу из нее. Как решить подобную задачу?
66. andrewks 1195 26.11.12 17:38 Сейчас в теме
в модуле для FPC не нашёл функцию V8SetPWideChar ( возврат в 1С строки, представленной в FPC типом PWideChar )

дописал. может, кому, пригодится:
function TV8UserObject.V8SetPWideChar(V: PV8Variant;
  Value: PWideChar): boolean;
var
  L, SZ: longword;
begin

  result := (Value = nil);
  if result then
    Exit;

  V8ClearVar(V);
  V.vt := VTYPE_PWSTR;
  L := Length(Value);
  SZ := (L + 1) * SizeOf(WideChar);

  result := V8MM.AllocMemory(@(V.VarEnum.vtRecWideString.pwstrVal), SZ);
  if result then
  begin
    Move(Value^, V.VarEnum.vtRecWideString.pwstrVal^, SZ);
    V.VarEnum.vtRecWideString.wstrLen := L;
  end;
end;

...Показать Скрыть
67. andrewks 1195 29.11.12 23:45 Сейчас в теме
в модуле для FPC ошибка в function _GetParamDefValue, вызывающая падение в случае, если параметры по умолчанию не заданы, а 1с видит, что методу передано меньше параметров и пытается запросить параметр по умолчанию

правильный вариант кода:

function _GetParamDefValue(Obj: PV8ObjectRec; const lMethodNum,
  lParamNum: integer; pvarParamDefValue: PV8Variant): boolean; stdcall;
var
ind: integer;
begin
  result := False;
  if Obj.RelObj1.ClassReg.MethList[lMethodNum].DefParams <> nil then
  begin
    for ind := 0 to length(Obj.RelObj1.ClassReg.MethList[lMethodNum].DefParams.Values)-1 do
    begin
      if (Obj.RelObj1.ClassReg.MethList[lMethodNum].DefParams.Values[ind].Num = lParamNum) then
      begin
        pvarParamDefValue^ := Obj.RelObj1.ClassReg.MethList[lMethodNum].DefParams.Values[ind].Value;
        result := True;
      end;
    end;
  end;
end;

...Показать Скрыть
68. Александр Соломатин (v77) 131 30.11.12 09:11 Сейчас в теме
(67) andrewks, Спасибо. Исправлю.
69. andrewks 1195 19.12.12 21:23 Сейчас в теме
что-то не ясен момент: в описании технологии Native API сказано, что BLOB (Двоичные данные) могут только возвращаться из компоненты в 1С, про передачу BLOB из 1С в компоненту ничего не сказано. при попытке передать ДвоичныеДанные в параметре метода 1С ругается на неверный параметр (до компоненты даже дело не доходит).
однако в Вашем модуле есть функция по получению BLOB V8AsBlob(). У Вас получилось передать ДвоичныеДанные в компоненту? не поделитесь рецептом?
70. Александр Соломатин (v77) 131 20.12.12 08:29 Сейчас в теме
(69) andrewks, я не помню, что пробовал. ну если не дает, то значит нельзя. А V8AsBlob() наверное на всякий случай сделал.
71. Осипов Сергей (fixin) 3521 20.12.12 18:07 Сейчас в теме
72. andrewks 1195 11.01.13 08:25 Сейчас в теме
73. Вадим Скакун (UncleVader) 125 24.01.13 12:12 Сейчас в теме
Раз уж добавили поддержку Lazarus, может попробуем и под Linux скомпилить?
Вот тут есть готовая виртуальная машина с установленным Lazarus, попробовал в нем скомпилить выложенную демку, но она не подключается в контексте сервера 1С под x64 Ubuntu. Есть мысли? Спасибо!
74. Александр Соломатин (v77) 131 24.01.13 12:30 Сейчас в теме
Мыслей нет. А что нибудь другое подключается в контексте сервера 1С под x64 Ubuntu?
75. andrewks 1195 24.01.13 12:34 Сейчас в теме
(73) UncleVader, там же написано, что под Android
76. Вадим Скакун (UncleVader) 125 24.01.13 12:44 Сейчас в теме
(74) v77, У меня нет к сожалению ни одной ВК под linux, поэтому трудно сказать, дал бы кто попробовать...
(75) andrewks, ну и что, главное что стоит настроенный Lazarus и компилит, в т.ч. и приложенный тут пример ВК
77. andrewks 1195 24.01.13 12:48 Сейчас в теме
(76) UncleVader, я к тому, что если у Вас есть доступ к серваку с убунтой х64, то, может, стоит скомпилить прямо на нём? у меня на ноуте стоит убунта, но она там х32
78. Вадим Скакун (UncleVader) 125 24.01.13 12:57 Сейчас в теме
(77) andrewks, Чтоб на нем скомпилить туда надо поставить Lazarus, а для меня это китайская грамота ((
Во вложении скомпиленная в упомянутой (73) системе, попробуйте может у Вас подключится
Прикрепленные файлы:
libdemo.so
79. Вадим Скакун (UncleVader) 125 24.01.13 17:23 Сейчас в теме
Поставил 64 Ubuntu, на него Lazarus, скомпилил пример - на сервере не подключается ((
80. Misha ⁠ (Magister) 132 10.02.13 02:39 Сейчас в теме
81. Сергей Садыхов (SerG_121) 432 11.02.13 13:53 Сейчас в теме
Почему когда я создаю поток у меня вылетает ошибка? В чем проблема? Код в прекрепленных файлах
Прикрепленные файлы:
1cComPort.rar
82. Александр Соломатин (v77) 131 11.02.13 14:11 Сейчас в теме
Ну ты в отладчике посмотри где глючит. А ProcessMessages тебе зачем? Поставь вместо ProcessMessages sleep(0) для начала.
83. Сергей Садыхов (SerG_121) 432 11.02.13 15:39 Сейчас в теме
(82)Я так и со слипом пробовал бесполезно! Попробуй у себя проверить мой код.
Выдает ошибку и вылетает 1с именно когда запускается поток ReadThread
84. andrewks 1195 11.02.13 16:12 Сейчас в теме
(83) SerG_121, видимо, у Вас исключение вылетает. попробуйте в try/except и выводить лог, может, прояснится
85. Александр Соломатин (v77) 131 11.02.13 16:46 Сейчас в теме
(83) SerG_121, Ты создаешь объект в 1с. Выполняешь его метод ОткрытьПорт. В методе ОткрытьПорт создается поток, который использует объект. Но объект после выполнения ОткрытьПорт автоматически убивается, но в потоке к нему есть обращение в Execute. Обращение к несуществующему объекту. Наверное по этому и глючит.
86. Сергей Садыхов (SerG_121) 432 12.02.13 07:38 Сейчас в теме
(85)Может подскажешь как реализовать?
87. Александр Соломатин (v77) 131 12.02.13 08:38 Сейчас в теме
А чего надо реализовать?
88. Сергей Садыхов (SerG_121) 432 12.02.13 08:47 Сейчас в теме
(87)Спасибо большое все разобрался )
89. Дмитрий Ерохин (TamDE) 26.02.13 20:11 Сейчас в теме
Собрал ВК в Lazarus.
Нашел небольшой глюк: если передать в функцию ФункцияПривет2 пустые строки, то платформа "валится"
//Рез = Об.ФункцияПривет2("Раз","Два");
Рез = Об.ФункцияПривет2("","");

Обошел путем добавления условия
    
if L > 0 then

перед строкой
       
Move(Value[1], V.VarEnum.vtRecWideString.pwstrVal^, SZ);

в методе V8SetWString
90. Misha ⁠ (Magister) 132 04.03.13 01:39 Сейчас в теме
В Linux таки не работает.
Платформа грузит .so, вызывает несколько функций и валится по SIGSEGV.
Вот что успевает вызвать:
[quote]
GetClassNames
GetClassObject
_setMemManager
_GetInfo
[/quote]
После этого падение. Пока причину понять не смог, может быть будут идеи?
91. Александр Соломатин (v77) 131 04.03.13 08:58 Сейчас в теме
(90) Magister, есть идея посмотреть в отладчике. линуксов у меня нету.
92. Misha ⁠ (Magister) 132 05.03.13 01:48 Сейчас в теме
(91) Отладчик ловит исключение, и в качестве адреса показывает нулевые адреса. Бред полный :)
Ещё немного поразбирался - судя по всему причина в том, что под Linux 1С компилируется с использованием GCC, а у него виртуальная таблица методов в памяти имеет другую структуру.
Получается что "грязный" хак, с помощью которого вообще работает эта библиотека не срабатывает, т.к. TV8ProcRec не соответствует IComponentBase.

Пока что удалось добиться таки вызова RegisterExtensionAs добавлением парочки пустых полей с типом Pointer, но теперь другая проблема - V8MM.AllocMemory() возвращает false...
93. andrewks 1195 05.03.13 08:30 Сейчас в теме
(89) TamDE, что-то не так в Вашем королевстве.
1. эта функция отвечает за возвращаемые значения, а не за передаваемые
2. L не может быть равно 0
3. у меня падения на пустых строках нет
94. andrewks 1195 05.03.13 08:35 Сейчас в теме
(92) Magister, а Вы на какой платформе, и на каком дистре лин тестируете?
95. Misha ⁠ (Magister) 132 05.03.13 18:43 Сейчас в теме
(94) Ubuntu 12.10 x32, 1C 8.3.2 x32 файловая.
На Windows с тем же релизом 1С всё хорошо.
96. andrewks 1195 07.03.13 22:10 Сейчас в теме
(95) Magister, немного наблюдений:

в Win 1с вызывает функции в таком порядке:
Initialization
GetClassObject()
_Init()
_setMemManager()
_SetLocale()
_GetInfo()
_RegisterExtensionAs()
...
_Done()
DestroyObject()
Finalization

в Lin:
Initialization
GetClassObject()
_setMemManager()
_GetInfo()
далее - падение до захода в _RegisterExtensionAs()

почему-то в линуксе обходится стороной _Init()
97. andrewks 1195 08.03.13 00:00 Сейчас в теме
(92) Magister, похоже, проблема с менеджером памяти. только у меня при попытке вызова AllocMemory() - сразу крах. пытаюсь в _setMemManager() вызвать AllocMemory() - в винде успешно, память выделяется, в лин - сразу крах.

что-то с описанием интерфейса, может? соглашение о вызове, думаю, тут ни при чём
98. Misha ⁠ (Magister) 132 08.03.13 04:24 Сейчас в теме
Просто структура класса не такая получается. Компилятор другой - вот и всё, баста.
Думаю, правильным путем было бы создание "обертки" на C++, которая бы уже общалась с FreePascal. Иначе гиблое это дело, как мне кажется...
Сейчас вот добился вызова методов:
[quote]GetClassNames
GetClassObject
_Init
_setMemManager
_RegisterExtensionAs[/quote]
Вот откуда тут _RegisterExtensionAs? Ведь, судя по логике, должен быть _SetLocale.
Вывод - в том месте, где у нас находится _RegisterExtensionAs, должен находится _SetLocale.
Это, в принципе, объясняет и падение на RegisterExtensionAs - т.к. SetLocale по параметрам отличается.

upd. Да, так и есть. Подставил туда _SetLocale - получил параметром строку своей локали. Т.е. я всё правильно понял.
99. andrewks 1195 08.03.13 08:55 Сейчас в теме
(98) Magister, эмм... если я правильно понимаю, то достаточно найти правильный порядок адресов в TV8ProcRec, зачем обёртка?
Оставьте свое сообщение