Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

NetObjectToIDispatch45

NetObjectToIDispatch45
Я
   San4opa
 
17.04.20 - 07:02
Добрый день

Хочу подключиться к веб сервису через оболочку "NetObjectToIDispatch45".
То есть не могу нигде найти аналог кода через NetObjectToIDispatch45 типа:

Определение = Новый WSОпределения(Объект.АдресСервера);
Прокси = Новый WSПрокси(Определение, Сервис.URIПространстваИмен,Сервис.Имя,Сервис.ТочкиПодключения[0].Имя);
   oleg_km
 
1 - 17.04.20 - 14:10
Мне кажется ты не понял концепцию. Ты должен сделать промежуточную сборку на .NET с объектами прослойками используя мастер .NET, а потом используя NetObjectToIDispatch45 пользовать это в 1С
   Serginio1
 
2 - 17.04.20 - 14:41
Олег привет!
В свое время писал что где и как API IE из 1с 7.7
   Garykom
 
3 - 17.04.20 - 14:48
(2) Подскажи есть ли где то пример ВК 1С на чистом C (без классов C++ с их эмуляцией на C)
   Serginio1
 
4 - 17.04.20 - 15:11
(2) Я особо то и не заморачивался. Брал их примеры. Но по большому то счету можно и самому сделать массив ссылок на методы типа VMT и передавать первым полем ссылку на неё. Там это несложно сделать.
   Garykom
 
5 - 17.04.20 - 15:17
(4) Несложно это если C++ отлично знаешь как и C.

А я пытаюсь это на Golang через CGO, который может c-shared dll.
https://habr.com/ru/company/mailru/blog/324250/
   Serginio1
 
6 - 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/
   Garykom
 
7 - 17.04.20 - 16:19
(6) О спасибо, особенно за ссылочку на хабр про VMT
   Serginio1
 
8 - 17.04.20 - 16:34
   v77
 
9 - 17.04.20 - 16:56
(3) На инфостарте лет 5 валяются примеры на паскале. Только учти, что надо делать вариант для GCC (Linux) и для VC++(Windows). У GCC и VC++ оно там по разному устроено.
   Serginio1
 
10 - 17.04.20 - 17:14
   Serginio1
 
11 - 17.04.20 - 17:37
Ну и там же посмотри bindings.inc и init.inc
   Serginio1
 
12 - 17.04.20 - 17:38
   Garykom
 
13 - 17.04.20 - 17:49
(9) (10) Варианты на паскале я видел но нифига из них не понял.
Точнее понял что через перечислимые типы, записи и указатели на все это дело эмулируют VMT для C++.
Но как это повторить на чистом C не понял.
   Garykom
 
14 - 17.04.20 - 17:50
(9) Каким то образом на Lazarus один код для NativeAPI и для Win и для Lin.
   Serginio1
 
15 - 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 где каждое поле это указатель на функцию определенного типа
   v77
 
16 - 17.04.20 - 18:10
(13) Ну прочитай книжку про Си и поймешь. За тебя никто этой ерундой заниматься всё равно не будет. Так что дерзай.
   v77
 
17 - 17.04.20 - 18:13
   San4opa
 
18 - 17.04.20 - 19:21
(1) А как сборку сделать?
   Serginio1
 
19 - 17.04.20 - 19:37
   San4opa
 
20 - 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;

Но я не совсем понимаю что вставлять в места где вопросы.
   DES
 
21 - 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(_ИмяФункции, УровеньЖурналаРегистрации.Информация);
   San4opa
 
22 - 18.04.20 - 17:30
(21) Не могу понять какое пространство имен указывать, при сборке я указал пространство имен ServiceSpark,сама dll - Spark, то есть должно быть вот так:

 Тип_ServiceClient = Врап.ПолучитьТипИзСборки("Spark.ServiceSpark.ServiceClient", ПутьКСборке);

Пробовал и в других вариациях, но везде пишет нет такого типа.
   oleg_km
 
23 - 18.04.20 - 18:02
Наверное вот этот тип ServiceSpark.ServiceClient. Приведи namespace из исходников твоей сборки
   San4opa
 
24 - 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...);
   Serginio1
 
27 - 18.04.20 - 19:45
(24) Смотри наверху файла. Типа  
namespace xxx.ServiceSpark {
 Твой класс скорее всего и будет xxx.ServiceSpark.iFaxWebServiceSoap  если конечно xxx. существует
   oleg_km
 
28 - 18.04.20 - 22:52
(24) Namespace="http://interfax.ru/ifax";; - это совсем не то
   San4opa
 
29 - 19.04.20 - 04:27
(28) другого нет
   San4opa
 
30 - 19.04.20 - 04:34
(27) ServiceSpark.iFaxWebServiceSoap вроде тип нашел но при создании Объекта ошибка

Произошла исключительная ситуация (mscorlib): Конструктор для типа "ServiceSpark.iFaxWebServiceSoap" не найден.

в сборке что-то не так сделал?
 
 Рекламное место пустует
   Serginio1
 
31 - 19.04.20 - 13:51
Тебе Des там кучу кода предоставил


Для начала, стоит почитать http://catalog.mista.ru/public/448668/
что бы создать тип нужно сначала загрузить сборку  

Сборк= врап.ЗагрузитьСборку(ПутьКТвоейDll);
    
  Тип_iFaxWebServiceSoap = Сборка.GetType("ServiceSpark.iFaxWebServiceSoap");

либо
Тип_iFaxWebServiceSoap = Врап.ПолучитьТипИзСборки("ServiceSpark.iFaxWebServiceSoap", ПутьКТвоейDll);
   Serginio1
 
32 - 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);
   Serginio1
 
33 - 19.04.20 - 14:02
Куки вроде можно просто создать Врап.СоздатьОбъект("System.Net.CookieContainer");
   San4opa
 
34 - 19.04.20 - 17:58
(31) (33) Этот код я заметил ранее, спасибо.
client = Врап.СоздатьОбъект(Тип_ServiceClient); на этом месте ошибка.
Произошла исключительная ситуация (mscorlib): Конструктор для типа "ServiceSpark.iFaxWebServiceSoap" не найден.
С адресом, биндингом то же самое.
   San4opa
 
35 - 19.04.20 - 18:14
(34) Такая ошибка если получать тип из сборки 
SparkService = врап.ПолучитьТипИзСборки("ServiceSpark.iFaxWebServiceSoap",ПутьКСборке);

а если получать через загрузки сборки Сборка = врап.загрузитьСборку(ПутьКСборке); то пишет Произошла исключительная ситуация (NetObjetToIDispatch45): Ссылка на объект не указывает на экземпляр объекта.
   Serginio1
 
36 - 19.04.20 - 18:46
То есть сборка неопределено?
Вообще положи сборку рядом с NetObjectToIDispatch45.dll
А вообще путь то валидный,
ФайлСборки = Новый Файл(ИмяФайлаСборки);

        Сборка_API = ФайлСборки.Существует();
   Serginio1
 
37 - 19.04.20 - 18:49
Кинь кудани будь свою dll и дай ссылку
   San4opa
 
38 - 19.04.20 - 19:19
   Serginio1
 
39 - 19.04.20 - 20:06
ServiceSpark.iFaxWebServiceSoapClient
   Serginio1
 
40 - 19.04.20 - 20:08
ServiceSpark.iFaxWebServiceSoap это интерфейс который реализует класс ServiceSpark.iFaxWebServiceSoapClient

client= врап.ПолучитьТипИзСборки("ServiceSpark.iFaxWebServiceSoapClient",ПутьКСборке);
   San4opa
 
41 - 19.04.20 - 21:57
(40) ServiceSpark.iFaxWebServiceSoapClient: Произошла исключительная ситуация (mscorlib): Данное имя сборки или база кода недействительны. (Исключение из HRESULT: 0x80131047)
   Serginio1
 
42 - 19.04.20 - 22:20
А вот здесь скорее всего проблема в том, что  NetObjectToIDispatch45.dll скомпилирована под .Net 4.6.1 а твоя сборка под .NETCoreApp,Version=v3.1

Проще выбрать проект "библиотека  классов .Net Framework"  и следующим шагом выбрать платформа 4.6.1
   Serginio1
 
43 - 19.04.20 - 22:30
При поиске шаблона выбрать Язык-C# Платформа-Windows Тип проекта библиотеак


Выбрать Библиотека классов (.Net Framework)
   Serginio1
 
44 - 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
   San4opa
 
45 - 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
   San4opa
 
46 - 20.04.20 - 01:54
   Serginio1
 
47 - 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);
   San4opa
 
48 - 20.04.20 - 16:23
(47) Всё получилось спасиба!!!
   DES
 
49 - 20.04.20 - 18:10
(48) 47+ и от меня тоже. ;)
   Serginio1
 
50 - 20.04.20 - 18:20
На здоровье! И вам спасибо, что мои труды не пропадают
   San4opa
 
51 - 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;


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.