|
NetObjectToIDispatch45 | ☑ | ||
---|---|---|---|---|
0
San4opa
17.04.20
✎
07:02
|
Добрый день
Хочу подключиться к веб сервису через оболочку "NetObjectToIDispatch45". То есть не могу нигде найти аналог кода через NetObjectToIDispatch45 типа: Определение = Новый WSОпределения(Объект.АдресСервера); Прокси = Новый WSПрокси(Определение, Сервис.URIПространстваИмен,Сервис.Имя,Сервис.ТочкиПодключения[0].Имя); |
|||
1
oleg_km
17.04.20
✎
14:10
|
Мне кажется ты не понял концепцию. Ты должен сделать промежуточную сборку на .NET с объектами прослойками используя мастер .NET, а потом используя NetObjectToIDispatch45 пользовать это в 1С
|
|||
2
Serginio1
17.04.20
✎
14:41
|
Олег привет!
В свое время писал что где и как API IE из 1с 7.7 |
|||
3
Garykom
гуру
17.04.20
✎
14:48
|
(2) Подскажи есть ли где то пример ВК 1С на чистом C (без классов C++ с их эмуляцией на C)
|
|||
4
Serginio1
17.04.20
✎
15:11
|
(2) Я особо то и не заморачивался. Брал их примеры. Но по большому то счету можно и самому сделать массив ссылок на методы типа VMT и передавать первым полем ссылку на неё. Там это несложно сделать.
|
|||
5
Garykom
гуру
17.04.20
✎
15:17
|
(4) Несложно это если C++ отлично знаешь как и C.
А я пытаюсь это на Golang через CGO, который может c-shared dll. https://habr.com/ru/company/mailru/blog/324250/ |
|||
6
Serginio1
17.04.20
✎
15:45
|
Понятно https://ru.wikipedia.org/wiki/Таблица_виртуальных_методов
class IInitDoneBase { public: virtual ~IInitDoneBase() {} /// Initializes component /** * @param disp - 1C:Enterpise interface * @return the result of */ virtual bool ADDIN_API Init(void* disp) = 0; /// Sets the memory manager /* * @param mem - pointer to memory manager interface. * @return the result of */ virtual bool ADDIN_API setMemManager(void* mem) = 0; /// Returns component version /** * @return - component version (2000 - version 2) */ virtual long ADDIN_API GetInfo() = 0; /// Uninitializes component /** * Component here should release all consumed resources. */ virtual void ADDIN_API Done() = 0; }; Я же не помню первым идет адрес деструктора,потом адрес Init. https://habr.com/ru/post/409565/ |
|||
7
Garykom
гуру
17.04.20
✎
16:19
|
(6) О спасибо, особенно за ссылочку на хабр про VMT
|
|||
8
Serginio1
17.04.20
✎
16:34
|
Кстати пример вызова виртуального метода из C#
https://ru.stackoverflow.com/questions/589886/Как-подружить-c-и-c-через-com-наиболее-простым-способом/592713#592713 |
|||
9
v77
17.04.20
✎
16:56
|
(3) На инфостарте лет 5 валяются примеры на паскале. Только учти, что надо делать вариант для GCC (Linux) и для VC++(Windows). У GCC и VC++ оно там по разному устроено.
|
|||
10
Serginio1
17.04.20
✎
17:14
|
||||
11
Serginio1
17.04.20
✎
17:37
|
Ну и там же посмотри bindings.inc и init.inc
|
|||
12
Serginio1
17.04.20
✎
17:38
|
||||
13
Garykom
гуру
17.04.20
✎
17:49
|
(9) (10) Варианты на паскале я видел но нифига из них не понял.
Точнее понял что через перечислимые типы, записи и указатели на все это дело эмулируют VMT для C++. Но как это повторить на чистом C не понял. |
|||
14
Garykom
гуру
17.04.20
✎
17:50
|
(9) Каким то образом на Lazarus один код для NativeAPI и для Win и для Lin.
|
|||
15
Serginio1
17.04.20
✎
17:58
|
Давай по порядку
TAddInDefBaseVTable = record _Destructor: procedure(This: PAddInDefBase); cdecl; AddError: function (This: PAddInDefBase; wcode: cushort; const source: PWideChar; const descr: PWideChar; scode: clong): cbool; stdcall; Read: function (This: PAddInDefBase; wszPropName: PWideChar; pVal: P1CVariant; pErrCode: pculong; errDescriptor: PPWideChar): cbool; stdcall; Write: function (This: PAddInDefBase; wszPropName: PWideChar; pVar: P1CVariant): cbool; stdcall; RegisterProfileAs: function (This: PAddInDefBase; wszProfileName: PWideChar): cbool; stdcall; SetEventBufferDepth: function (This: PAddInDefBase; lDepth: clong): cbool; stdcall; GetEventBufferDepth: function (This: PAddInDefBase): clong; stdcall; ExternalEvent: function (This: PAddInDefBase; wszSource: PWideChar; wszMessage: PWideChar; wszData: PWideChar): cbool; stdcall; CleanEventBuffer: procedure (This: PAddInDefBase); stdcall; SetStatusLine: function (This: PAddInDefBase; wszStatusLine: PWideChar): cbool; stdcall; ResetStatusLine: procedure (This: PAddInDefBase); stdcall; end; это на самом деле struct где каждое поле это указатель на функцию определенного типа |
|||
16
v77
17.04.20
✎
18:10
|
(13) Ну прочитай книжку про Си и поймешь. За тебя никто этой ерундой заниматься всё равно не будет. Так что дерзай.
|
|||
17
v77
17.04.20
✎
18:13
|
+(13) на вот тебе еще для понимания https://stackoverflow.com/questions/15921372/c-virtual-table-layout-of-mimultiple-inheritance/35970952
|
|||
18
San4opa
17.04.20
✎
19:21
|
(1) А как сборку сделать?
|
|||
19
Serginio1
17.04.20
✎
19:37
|
||||
20
San4opa
18.04.20
✎
00:20
|
(19) Сборку сделал, дальше я так понимаю нужно подключиться к сервису типа:
врап=новый COMОбъект("NetObjectToIDispatch45"); Service=Врап.ПолучитьТипИзСборки("???",ПутьКСборке); // Create a webrequest with the specified URL. client = Врап.СоздатьОбъект(Service); client.Url = "???.svc";; cookieContainer = Врап.СоздатьОбъект("System.Net.CookieContainer"); client.CookieContainer = cookieContainer; Но я не совсем понимаю что вставлять в места где вопросы. |
|||
21
DES
18.04.20
✎
10:11
|
Вот кусок кода рабочего (ну может внес ошибки при затирании личной инфы)
Результат = Неопределено; ФайлВрап = "NetObjectToIDispatch45"; Попытка Врап = Новый COMОбъект(ФайлВрап); Врап.ВыводитьСообщениеОбОшибке = Ложь; Assembly = Врап.ТипКакОбъект(Врап.ПолучитьТип(ФайлВрап + ".GlobalContext1C")).Assembly; Исключение Assembly = Неопределено; КонецПопытки; Если НЕ Assembly=Неопределено Тогда ФайлВрап = Новый Файл(Assembly.Location); ПутьКФайлам = ФайлВрап.Путь; ИмяФайлаСборки = "Service_ТВОЯ.dll"; ПространствоИмен = "Service_ТВОЯ.ServiceReference."; ИмяФайлаСборки = ПутьКФайлам + ИмяФайлаСборки; ФайлСборки = Новый Файл(ИмяФайлаСборки); Сборка_API = ФайлСборки.Существует(); Если Сборка_API Тогда Попытка Тип_ServiceClient = Врап.ПолучитьТипИзСборки(ПространствоИмен + "ServiceClient", ФайлСборки.ПолноеИмя); Исключение Тип_ServiceClient = Неопределено; КонецПопытки; КонецЕсли; Если Тип_ServiceClient=Неопределено Тогда EF.ОбработкаОшибкиСlientE("Сервис API недоступен"); Возврат Неопределено; Иначе Если ТипЗнч(_ПараметрыФункции)=Тип("Структура") Тогда #Область Сlient UserName = "НАМЕ"; PassWord = "ПАСВОРД"; Http = "Http"; BasicHttpBinding = Врап.ПолучитьТипИзСборки("System.ServiceModel.Basic" + Http + "Binding", "System.ServiceModel.dll"); Binding = Врап.СоздатьОбъект(BasicHttpBinding, Врап.ПолучитьТип("System.ServiceModel.Basic" + Http + "SecurityMode").TransportWithMessageCredential); Binding.MaxBufferPoolSize = 1024 * 1024 * 2; Binding.MaxBufferSize = 1024 * 1024 * 1; Binding.MaxReceivedMessageSize = 1024 * 1024 * 1; Address = Врап.СоздатьОбъект("System.ServiceModel.EndpointAddress", "https://ТВОЙ.АДРЕС.РУ"); Попытка СlientE = Врап.СоздатьОбъект(Тип_ServiceClient, Binding, Address); СlientE.ClientCredentials.UserName.UserName = ?(ПустаяСтрока(_UserName), UserName, _UserName); СlientE.ClientCredentials.UserName.Password = ?(ПустаяСтрока(_Password), PassWord, _Password); Исключение EF.ОбработкаОшибкиСlientE(Врап.ПоследняяОшибка); СlientE = Неопределено; КонецПопытки; #КонецОбласти Если НЕ СlientE=Неопределено Тогда EF.ОбработкаОшибкиСlientE(_ИмяФункции, УровеньЖурналаРегистрации.Информация); |
|||
22
San4opa
18.04.20
✎
17:30
|
(21) Не могу понять какое пространство имен указывать, при сборке я указал пространство имен ServiceSpark,сама dll - Spark, то есть должно быть вот так:
Тип_ServiceClient = Врап.ПолучитьТипИзСборки("Spark.ServiceSpark.ServiceClient", ПутьКСборке); Пробовал и в других вариациях, но везде пишет нет такого типа. |
|||
23
oleg_km
18.04.20
✎
18:02
|
Наверное вот этот тип ServiceSpark.ServiceClient. Приведи namespace из исходников твоей сборки
|
|||
24
San4opa
18.04.20
✎
18:40
|
(23) Не подходит.
[System.ServiceModel.ServiceContractAttribute(Namespace="http://interfax.ru/ifax", ConfigurationName="ServiceSpark.iFaxWebServiceSoap")] |
|||
25
Сияющий в темноте
18.04.20
✎
19:33
|
таблица виртуальных функций-это просто указатель в начале обьекта и ее можно рассматртвать как void*
в ней каждая запись-это указатель на функцию,то есть тоже void* типы и параметры функций определяются уже из описания класса или интерфейса по совести говоря,в Си ++ нет интерфейсов,а есть только классы. для обьектов со сложным наследованием в классе может быть несколько таблиц по одной для каждого класса. на самом деле,сложное наследование-вещь в себе,так как для возможности приведения обьекта к родительским-задача не тривиальная,так как одно и то же поле может быть у разных родителей-в это случае,компиллятор также должен вместо поля размещать ссылкк на него в разных местах обьекта. |
|||
26
Сияющий в темноте
18.04.20
✎
19:40
|
и вызов виртупльной функции обьекта-это очень просто:
((ObjectRefVar->lpVtbl)(ObjectVtblRef*))->pFunction(Object,Parameters...); |
|||
27
Serginio1
18.04.20
✎
19:45
|
(24) Смотри наверху файла. Типа
namespace xxx.ServiceSpark { Твой класс скорее всего и будет xxx.ServiceSpark.iFaxWebServiceSoap если конечно xxx. существует |
|||
28
oleg_km
18.04.20
✎
22:52
|
(24) Namespace="http://interfax.ru/ifax"; - это совсем не то
|
|||
29
San4opa
19.04.20
✎
04:27
|
(28) другого нет
|
|||
30
San4opa
19.04.20
✎
04:34
|
(27) ServiceSpark.iFaxWebServiceSoap вроде тип нашел но при создании Объекта ошибка
Произошла исключительная ситуация (mscorlib): Конструктор для типа "ServiceSpark.iFaxWebServiceSoap" не найден. в сборке что-то не так сделал? |
|||
31
Serginio1
19.04.20
✎
13:51
|
Тебе Des там кучу кода предоставил
Для начала, стоит почитать http://catalog.mista.ru/public/448668/ что бы создать тип нужно сначала загрузить сборку Сборк= врап.ЗагрузитьСборку(ПутьКТвоейDll); Тип_iFaxWebServiceSoap = Сборка.GetType("ServiceSpark.iFaxWebServiceSoap"); либо Тип_iFaxWebServiceSoap = Врап.ПолучитьТипИзСборки("ServiceSpark.iFaxWebServiceSoap", ПутьКТвоейDll); |
|||
32
Serginio1
19.04.20
✎
13:59
|
Ну и если у тебя в конструкторе прописан адрес и биндинг можешь создать
Сlient = Врап.СоздатьОбъект(Тип_ServiceClient); Можешь по биндигу и адресу client = Врап.СоздатьОбъект(Тип_ServiceClient, Binding, Address); client = Врап.СоздатьОбъект(Тип_ServiceClient); client.Url = url; CookieContainer= Врап.ПолучитьТипИзСборки("System.Net.CookieContainer", "System.dll"); client.CookieContainer = Врап.СоздатьОбъект(CookieContainer()); // Авторизация на сервисе. (должны быть включены cookies) result = client.Authmethod(login, password); |
|||
33
Serginio1
19.04.20
✎
14:02
|
Куки вроде можно просто создать Врап.СоздатьОбъект("System.Net.CookieContainer");
|
|||
34
San4opa
19.04.20
✎
17:58
|
(31) (33) Этот код я заметил ранее, спасибо.
client = Врап.СоздатьОбъект(Тип_ServiceClient); на этом месте ошибка. Произошла исключительная ситуация (mscorlib): Конструктор для типа "ServiceSpark.iFaxWebServiceSoap" не найден. С адресом, биндингом то же самое. |
|||
35
San4opa
19.04.20
✎
18:14
|
(34) Такая ошибка если получать тип из сборки
SparkService = врап.ПолучитьТипИзСборки("ServiceSpark.iFaxWebServiceSoap",ПутьКСборке); а если получать через загрузки сборки Сборка = врап.загрузитьСборку(ПутьКСборке); то пишет Произошла исключительная ситуация (NetObjetToIDispatch45): Ссылка на объект не указывает на экземпляр объекта. |
|||
36
Serginio1
19.04.20
✎
18:46
|
То есть сборка неопределено?
Вообще положи сборку рядом с NetObjectToIDispatch45.dll А вообще путь то валидный, ФайлСборки = Новый Файл(ИмяФайлаСборки); Сборка_API = ФайлСборки.Существует(); |
|||
37
Serginio1
19.04.20
✎
18:49
|
Кинь кудани будь свою dll и дай ссылку
|
|||
38
San4opa
19.04.20
✎
19:19
|
||||
39
Serginio1
19.04.20
✎
20:06
|
ServiceSpark.iFaxWebServiceSoapClient
|
|||
40
Serginio1
19.04.20
✎
20:08
|
ServiceSpark.iFaxWebServiceSoap это интерфейс который реализует класс ServiceSpark.iFaxWebServiceSoapClient
client= врап.ПолучитьТипИзСборки("ServiceSpark.iFaxWebServiceSoapClient",ПутьКСборке); |
|||
41
San4opa
19.04.20
✎
21:57
|
(40) ServiceSpark.iFaxWebServiceSoapClient: Произошла исключительная ситуация (mscorlib): Данное имя сборки или база кода недействительны. (Исключение из HRESULT: 0x80131047)
|
|||
42
Serginio1
19.04.20
✎
22:20
|
А вот здесь скорее всего проблема в том, что NetObjectToIDispatch45.dll скомпилирована под .Net 4.6.1 а твоя сборка под .NETCoreApp,Version=v3.1
Проще выбрать проект "библиотека классов .Net Framework" и следующим шагом выбрать платформа 4.6.1 |
|||
43
Serginio1
19.04.20
✎
22:30
|
При поиске шаблона выбрать Язык-C# Платформа-Windows Тип проекта библиотеак
Выбрать Библиотека классов (.Net Framework) |
|||
44
Serginio1
19.04.20
✎
22:36
|
Или в проекте Целевая Рабочая среда поменять на
.Net Framework 4.6.1 https://docs.microsoft.com/ru-ru/visualstudio/ide/visual-studio-multi-targeting-overview?view=vs-2019 |
|||
45
San4opa
20.04.20
✎
01:50
|
(44) Пересоздал, но пока все равно ошибка
Если пишу так SparkService = врап.ПолучитьТипИзСборки("SparkObmen.ServiceSpark.iFaxWebServiceSoapClient",ПутьКСборке); client = Врап.СоздатьОбъект(SparkService); пишет Произошла исключительная ситуация (mscorlib): Адресат вызова создал исключение. Если так BasicHttpBinding = Врап.ПолучитьТипИзСборки("System.ServiceModel.BasicHttpBinding", "System.ServiceModel.dll"); Binding = Врап.СоздатьОбъект(BasicHttpBinding, Врап.ПолучитьТип("System.ServiceModel.BasicHttpSecurityMode").TransportWithMessageCredential); Address = Врап.СоздатьОбъект("System.ServiceModel.EndpointAddress","http://sparkgatetest.interfax.ru/iFaxWebService/iFaxWebService.asmx"); client = Врап.СоздатьОбъект(SparkService, Binding, Address); client.Authmethod(Объект.Логин,Объект.Пароль); То пишет вот что: https://drive.google.com/file/d/1e9QMgqJ8ixfN-4-5k5SYywAeiVQlX3nB/view?usp=sharing |
|||
46
San4opa
20.04.20
✎
01:54
|
||||
47
Serginio1
20.04.20
✎
11:23
|
врап=новый COMОбъект("NetObjectToIDispatch45");
SparkService = врап.ПолучитьТипИзСборки("SparkObmen.ServiceSpark.iFaxWebServiceSoapClient",ПутьКСборке); BasicHttpBinding = Врап.ПолучитьТипИзСборки("System.ServiceModel.BasicHttpBinding", "System.ServiceModel.dll"); Binding = Врап.СоздатьОбъект(BasicHttpBinding); Address = Врап.СоздатьОбъект("System.ServiceModel.EndpointAddress","http://sparkgatetest.interfax.ru/iFaxWebService/iFaxWebService.asmx"); client = Врап.СоздатьОбъект(SparkService,Binding,Address); |
|||
48
San4opa
20.04.20
✎
16:23
|
(47) Всё получилось спасиба!!!
|
|||
49
DES
20.04.20
✎
18:10
|
(48) 47+ и от меня тоже. ;)
|
|||
50
Serginio1
20.04.20
✎
18:20
|
На здоровье! И вам спасибо, что мои труды не пропадают
|
|||
51
San4opa
01.06.20
✎
23:43
|
(50) Добрый день
Подскажите еще пожалуйста вопрос есть: пробую отправить запрос на сервер с Basic auth Написал код, но сервер ничего не отвечает, мне кажется с авторизацией что-то не так делаю. uriSources = Объект.АдресСервера+"/score/sync"; requestUri = ""; NetObject = Новый COMОбъект("NetObjectToIDispatch45"); HttpClient = NetObject.ПолучитьТипИзСборки("System.Net.Http.HttpClient","System.Net.Http.dll"); HttpClientHandler = NetObject.ПолучитьТип("System.Net.Http.HttpClientHandler"); handler = NetObject.СоздатьОбъект(HttpClientHandler); NetworkCredential = NetObject.СоздатьОбъект("System.Net.NetworkCredential"); NetworkCredential.UserName = Объект.Логин; NetworkCredential.Password = Объект.Пароль; handler.Credentials = NetworkCredential; handler.UseDefaultCredentials = Истина; Client = NetObject.СоздатьОбъект(HttpClient,handler); uri = NetObject.СоздатьОбъект("System.Uri",uriSources); Client.BaseAddress = uri; Данные = Новый Структура(); Данные.Вставить("inn","6140038703"); СтрокаJSON = Плейн_РаботаСHTTP.ПолучитьСтрокуJSON(Данные); ПараметрыЗапросаNetObject = NetObject.ОбернутьЛюбойОбъект(СтрокаJSON); StringContent = NetObject.ПолучитьТип("System.Net.Http.StringContent"); Контент = NetObject.СоздатьОбъект(StringContent,ПараметрыЗапросаNetObject); Результат = Client.PostAsync(requestUri,Контент).Result; //Result = Результат.Content.ReadAsStringAsync().Result; |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |