![]() |
![]() |
|
v8: ВК NativeAPI и Delphi - Invalid pointer operation | ☑ | ||
---|---|---|---|---|
0
igor_kav
30.03.12
✎
20:32
|
Для написания ВК использую NativeAPI (http://infostart.ru/public/81644/).
Пару функций удалось сделать и использовать в 1С, но написал третью функцию в dll... при попытке использования в 1с именно этой третьей функции, 1с вылетает с ошибкой "Программа 1Сv8 не работает Возникшая проблема привела к прекращению работы программы. бла-бла". Самое интересное, что для тестирования создал проект VLC на delphi, поместил в него код функции. В VLC-проекте ФУНКЦИЯ РАБОТАЕТ! Поставил исключение в процедуре _CallAsFunc и получил ошибку: Внешняя компонента : Invalid pointer operation. Ошибка! {Форма.Форма.Форма(473)}: Ошибка при вызове метода контекста (ПолучитьМоиДанные): Ошибка внешней компоненты Прочитал, что СКОРЕЕ ВСЕГО УТЕЧКА ПАМЯТИ ИЗ-ЗА ИСПОЛЬЗОВАНИЯ STRING, но как решить ума не приложу... Кто сталкивался, ПОМОГИТЕ! |
|||
1
igor_kav
30.03.12
✎
20:43
|
вот код
[code] 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. [/code] |
|||
2
igor_kav
30.03.12
✎
20:44
|
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. |
|||
3
igor_kav
30.03.12
✎
20:46
|
не могу нормально скопировать код ВК. вот ссылка на комментарии к NativeApi http://forum.infostart.ru/forum24/topic38092/, там есть мой код ВК
|
|||
4
romix
30.03.12
✎
20:47
|
Вот еще дельфийский пример http://infostart.ru/public/88060/
|
|||
5
igor_kav
30.03.12
✎
21:04
|
Я смотрел Вашу работу, от туда и взял код на обработку исключения :), но увы, смог выявить только ошибку, а вот как ее исправить ума не приложу. Что можете посоветовать?
|
|||
6
romix
30.03.12
✎
21:21
|
(5) Попробуйте ее как шаблон использовать - там больше функций, и я что-то исправлял (уже не помню что).
|
|||
7
romix
30.03.12
✎
21:22
|
Т.е. не меняя числа функций - а то может где-то чего-то забыли там изменить под новое число функций.
|
|||
8
vmv
30.03.12
✎
21:37
|
(0) 1С очень критичка к г-коду самопальных библиотек, ведь разработчики платформы далеко не глупы
|
|||
9
igor_kav
30.03.12
✎
21:42
|
(6) Взял полностью Ваш переработанный модуль v8napi, то теперь 1С вываливаентся при вызове любой функции :(
|
|||
10
igor_kav
31.03.12
✎
01:28
|
Отладчиком выявил ошибку "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 все нормально работает. В чем же все-таки причина? |
|||
11
H A D G E H O G s
31.03.12
✎
01:45
|
Фиг тя знает..
ЗначениеИзСтрокиВнутр - фиии, реальне пацаны юзают XDTO. У меня даже объекты для формирования строкого возврата Массива, СпискаЗначений и Структуры есть. Вот темка: v8: Сериализация СпискаЗначений В XDTO. Где я не прав? |
|||
12
H A D G E H O G s
31.03.12
✎
01:48
|
Вообще - ужастный адскый код.
|
|||
13
H A D G E H O G s
31.03.12
✎
01:48
|
THTTPRIO - че за зверь, неужели типовые Indyйцы не устаривают?
|
|||
14
igor_kav
31.03.12
✎
01:54
|
THTTPRIO использую для работы с веб-сервисом, одно непонятно почему в EXE работает, а вот в DLL ну НИКАК?
|
|||
15
H A D G E H O G s
31.03.12
✎
02:21
|
Попробуй тупо после try, Перед (RIO as AllegroWebApiPortType).doGetMyData(....
написать CoInitializeEx(nil, COINIT_MULTITHREADED); |
|||
16
igor_kav
31.03.12
✎
09:31
|
(15) попробовал, результат нулевой :(
Какие еще будут варианты? |
|||
17
romix
31.03.12
✎
14:18
|
Вариант - взять работающую DLL и не меняя в ней число функций запустить в одной из них свою требуемую функцию. Тогда станет ясно в чем проблема - в коде обвязки или в коде функции.
Или наоборот - заменить содержимое своей функции на что-то нейтральное типа sleep или MessageBox, и посмотреть а будет ли работать так. Если нет то неправильно написана обвязка, если да - то пошагово проверять свою функцию (например повтыкать везде MessageBox-ы для отладки, на каком споткнется там и ошибка. |
|||
18
igor_kav
31.03.12
✎
15:16
|
(11) Как передать функции XDTO пакет (ТаблицаЗначений), а потом его в delphi разобрать?
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |