Имя: Пароль:
1C
1С v8
Вопрос по NetObjectToIDispatch
,
0 oleg_km
 
09.05.13
21:51
Попробовал v8: Объекты Net в IDispatch вроде все нормально.

Попробовал:

ТипПорт = объект.GetTypeByStr("System.IO.Ports.SerialPort");
Здесь ругается: Can't resolve type

Активатор = объект.Activator;
обПорт = Активатор.CreateInstance(ТипПорт);
   
обПорт.PortName = "COM43";
обПорт.BaudRate = 115200;
обПорт.ReadTimeout = 500;
обПорт.Open();
   
обПорт.Write("AT" + Символы.ВК);
Сообщить(обПорт.ReadExisting());
обПорт.Close();

Ругается:
1 oleg_km
 
09.05.13
22:08
Точнее:

Произошла исключительная ситуация (mscorlib): Could not resolve type 'System.IO.Ports.SerialPort'.
2 Jaap Vduul
 
09.05.13
23:23
дотнет фрэймворк, наверное, старенький...
3 oleg_km
 
10.05.13
09:05
Стоит 4, но я так понимаю при запуске подхватилась двойка или как это происходит?
4 oleg_km
 
10.05.13
09:53
Спасибо за наводку, вот так заработало:

ТипПорт = объект.GetTypeByStr("System.IO.Ports.SerialPort, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "");
5 oleg_km
 
10.05.13
13:09
Теперь возник вопрос с конструктором с параметрами и по поводу использования перечислений:

       ТипСокет = объект.GetTypeByStr("System.Net.Sockets.Socket, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "");
       ТипАдрес = объект.GetTypeByStr("System.Net.Sockets.AddressFamily, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "");
       ТипТип = объект.GetTypeByStr("System.Net.Sockets.SocketType, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "");
       ТипПротокол = объект.GetTypeByStr("System.Net.Sockets.ProtocolType, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "");
       
       //мсИсх = Новый Массив;
       //мсИсх.Добавить(ТипАдрес.InterNetwork);
       //мсИсх.Добавить(ТипТип.Stream);
       //мсИсх.Добавить(ТипПротокол.Tcp);
       //мс = Новый COMSafeArray(мсИсх, "VT_VARIANT");
       
       //обСокет = Активатор.CreateInstance(ТипСокет, ТипАдрес.InterNetwork, ТипТип.Stream, ТипПротокол.Tcp);
       обСокет = Активатор.CreateInstance(ТипСокет, 2, 1, 6);

На ТипАдрес.InterNetwork ругается метод не найден, хотя в отладчике виден, в CreateInstance не понятно как передать массив параметров
6 oleg_km
 
10.05.13
14:09
Вот вроде должен быть правильный вариант:

       ТипСокет = объект.GetTypeByStr("System.Net.Sockets.Socket, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "");
       ТипАдрес = объект.GetTypeByStr("System.Net.Sockets.AddressFamily, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "");
       ТипТип = объект.GetTypeByStr("System.Net.Sockets.SocketType, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "");
       ТипПротокол = объект.GetTypeByStr("System.Net.Sockets.ProtocolType, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "");
       
       мсПарам = объект.CreateArray("System.Object", 3);
       мсПарам.SetValue(ТипАдрес.InterNetwork, 0);
       мсПарам.SetValue(ТипТип.Stream, 1);
       мсПарам.SetValue(ТипПротокол.Tcp, 2);

       обСокет = Активатор.CreateInstance(ТипСокет, мсПарам);

Но на ТипАдрес.InterNetwork ругается. Автор, подскажи, что не так?
7 Serginio1
 
10.05.13
14:55
Ты сначала на шарпе оттести, затем в 1С перенеси. А эта библиотека просто Оле обертка нетовских объектов. Там есть сложности с некоторыми типами но они решаемы
http://rsdn.ru/forum/dotnet/4320177

Вот последний рабочий вариант http://rsdn.ru/forum/dotnet/4719475
8 oleg_km
 
10.05.13
15:08
(7) На шарпе все работает. Проблема судя по всему, что неправильно создается обертка для перечислений (enum), т.к. я сделал тестовый пример, где нужный енум возвращается из шарпа и все заработало:

       public object Get1()
       {
           return new AutoWrap(AddressFamily.InterNetwork);
       }

       public object Get2()
       {
           return new AutoWrap(SocketType.Stream);
       }

       public object Get3()
       {
           return new AutoWrap(ProtocolType.Tcp);
       }


       мсПарам.SetValue(объект.Get1(), 0);
       мсПарам.SetValue(объект.Get2(), 1);
       мсПарам.SetValue(объект.Get3(), 2);

Можешь подсказать что добавить в товй компонент, чтобы он правильно обрабатыал перечисления?
9 Serginio1
 
10.05.13
15:08
А вообще у InterNetwork значение 2
то есть должно быть мсПарам.SetValue(ТипАдрес, 2);
10 Serginio1
 
10.05.13
15:10
Вернее  Активатор.CreateInstance(ТипАдрес, мсПарам);
11 Serginio1
 
10.05.13
15:12
(10) не совсем верно это получение значения. Должно работать мсПарам.SetValue(ТипАдрес, 2); так как в рефлекторе InterNetwork = 2
12 oleg_km
 
10.05.13
15:12
то есть должно быть мсПарам.SetValue(ТипАдрес, 2);

Нет 2 - это же индекс в массиве, еще раз, вот ключевая часть кода:

мсПарам = объект.CreateArray("System.Object", 3);
мсПарам.SetValue(ТипАдрес.InterNetwork, 0);
мсПарам.SetValue(ТипТип.Stream, 1);
мсПарам.SetValue(ТипПротокол.Tcp, 2);
обСокет = Активатор.CreateInstance(ТипСокет, мсПарам);

Типы все получены, но получить конкретное перечисление не получается. Я пытался подсунуть массив целых с указанием значений перечислений, но дот нет заругался, что нет такого конструктора (с целыми параметрами), что логично, т.к. шарп не делает неявного приведения.
13 Serginio1
 
10.05.13
15:13
надо будет перечисления посмотретьДа понял Попробуй так
Активатор.CreateInstance(ТипАдрес, мсПарам);
мсПарам.SetValue(Активатор.CreateInstance(ТипАдрес, мсПарам), 0);
14 Serginio1
 
10.05.13
15:14
Тьфу мсПарам.SetValue(Активатор.CreateInstance(ТипАдрес, 2), 0);
15 Serginio1
 
10.05.13
15:19
Или object obj1 = Enum.ToObject(ТипАдрес, "InterNetwork");
16 oleg_km
 
10.05.13
15:23
(14) Сказал нет такого конструктора

(15) А этоя вообще не понял как перевести на 1С. Enum это чей член?
17 Serginio1
 
10.05.13
15:27
То есть Активатор.CreateInstance(ТипАдрес, 2) для энума не идет?
объект.GetTypeByStr("System.Enum")
18 Serginio1
 
10.05.13
15:31
Или сделай метод public object ПолучитьПеречисление(Тип,Предствление)
       {
           return new AutoWrap(Enum.ToObject(Тип,Представление);
       }
19 Serginio1
 
10.05.13
15:36
Я в новой версии добавил два метода

public object CreateObject(string type)
       { return new AutoWrap(System.Activator.CreateInstance(Type.GetType(type))); }

       public object CreateObjectWhithParam(string type,Object[] args)
       { return new AutoWrap(System.Activator.CreateInstance(Type.GetType(type), args)); }
20 Serginio1
 
10.05.13
15:42
А вообще то Энум это чтсло и должно проходить как
сПарам.SetValue(2, 0);
21 oleg_km
 
10.05.13
15:47
(21) Я же писал: так не катит, он потом говорит, не конструктора с типом целый. Ну и в букваре написано, что неявные преобразования целых в перечисления не производятся. Можно наверное попробовать сделать функцию аналог as. типа на входе тип и исходное значение, на выходе объект перечисления. Но я хочу сделать все-таки через имя. Сейчас кухню допылесосю и попробую
22 Serginio1
 
10.05.13
15:56
21 Тогда сделай 18.  
В 20 там установка сПарам.SetValue(2, 0);
Установить значение то он даст а вот на вызове
обСокет = Активатор.CreateInstance(ТипСокет, мсПарам);  саоткнется
23 Serginio1
 
10.05.13
16:01
Кстати Enum.ToObject подходит и для чисел http://msdn.microsoft.com/en-us/library/e3c9ct1y.aspx
24 oleg_km
 
10.05.13
16:11
(18)
public object ПолучитьПеречисление(Тип,Предствление)
{
  return new AutoWrap(Enum.ToObject(Тип,Представление);
}

я сделал:
public object ПолучитьПеречисление(Тип, string Предствление)
{
  return new AutoWrap(Enum.Parse(Тип, Представление);
}

а вот какой тип должен иметь Тип. Если Type, то падает в момент вызова неизвестная ошибка, если объект, то падает при приведении
25 oleg_km
 
10.05.13
16:19
Все, получилось. Я примерно понял в каком направлении рыть. Съезжу яхту покрашу и вечером попробую сделать финальный вариант.
26 Serginio1
 
10.05.13
16:28
http://msdn.microsoft.com/en-us/library/dd783499.aspx
не совсем подходит. Там дженерики. По ним отдельная рефлексия
public static bool TryParse<TEnum>(
   string value,
   out TEnum result
)
where TEnum : struct

А 18 не проходит? По идее должен походить для предствления ввиде интов и строк.
http://stackoverflow.com/questions/29482/cast-int-to-enum-in-c-sharp
27 Serginio1
 
10.05.13
16:44
Немного не в тему у Enum есть метод
public static object Parse(Type enumType, string value)
{
   return Parse(enumType, value, false);
}
вообще то должен быть Type.
Посмотри новый вариант там есть
public object ТипКакОбъект(object Тип)
       {
           Type T=((Type)Тип);

           return new AutoWrap(T, T.GetType());
       }
28 Serginio1
 
10.05.13
16:53
Непомню зачем тестил объект=Новый COMОбъект("NetObjectToIDispatch");
   
   Массив=объект.CreateArray("System.String",100);
   для сч=0 по 99 Цикл
       Массив.SetValue(Строка(сч),сч);
   КонецЦикла;
   
   Для каждого стр из Массив Цикл
       Сообщить(стр);
   КонецЦикла;
   
   
   ЛистТип=объект.ПолучитьТип("System.Collections.Generic.List`1[System.String]","");
   //ЛистТип=объект.ПолучитьТип("System.Collections.ArrayList","");
    Лист=объект.Activator.CreateInstance(ЛистТип);
   // Массив=Лист.ToArray();
    Массив=объект.ВыполнитьМетод(Лист,"ToArray");
   
    Тип=объект.ТипКакОбъект(ЛистТип);
    Методы=Тип.GetMethods();
   Методы=объект.ПолучитьМетоды(ЛистТип);
    Для каждого стр из Методы Цикл
        Сообщить(Стр.Name);
    КонецЦикла;
    Для сч=1 по 100 Цикл
    Лист.Add(""+Сч);
    КонецЦикла;
   Сообщить(Лист.Count);
   Стр=Лист.ToString();
   Сообщить(Стр);
   //Массив=объект.ПолучитьМассивИзЛистаСтрок(Лист);
   //    Для каждого стр из массив Цикл
   //    Сообщить(Стр);
   //КонецЦикла;
 //   Массив=Лист.ToArray();
   Массив=объект.ВыполнитьМетод(Лист,"ToArray");
   Тип=Лист.GetType();
//    Массив=Лист.ToArray(объект.ПолучитьТип("System.String",""));
   Сообщить(Массив.ToString());
       Для каждого стр из массив Цикл
       Сообщить(Стр);
   КонецЦикла;
29 Serginio1
 
10.05.13
16:56
public object ПолучитьМетоды(object Тип)
       {
        //   AutoWrap T = ((AutoWrap)Тип);
        //   return T.T.GetMethods();

           return new AutoWrap(((Type)Тип).GetMethods());
       }

То есть в
public object ПолучитьПеречисление(object  Тип,string  Предствление)
       {
           return new AutoWrap(Enum.ToObject((Type) Тип,Представление);
       }
30 Serginio1
 
10.05.13
18:18
То есть нужно тип постоянно приводить. Вот такая засада.
31 Serginio1
 
10.05.13
18:30
Либо в ОбернутьОбъект(object obj) добавить


if (obj is Type) obj = new AutoWrap((Type)obj);
32 Serginio1
 
10.05.13
18:38
Тьфу прошу прощения в новой версии уже есть
if (ЭтоТип)
               obj = T.InvokeMember(name, invokeAttr, binder, null, args, modifiers, culture, namedParameters);
           else
               obj = T.InvokeMember(name, invokeAttr, binder, O, args, modifiers, culture, namedParameters);

А вот для передаваемого параметра нужно добавить проверку на тип

if (args != null && args.Length > 0)
           {
               for (int x = 0; x < args.Length; x++)
               {
                   if (args[x] is AutoWrap)
                    if (args[x].ЭтоТип)
{args[x] = (Type)((AutoWrap)args[x]).O;}
else
                   { args[x] = ((AutoWrap)args[x]).O; }
               }
           }
или {args[x] = (Type)((AutoWrap)args[x]).T;}
33 zladenuw
 
10.05.13
19:17
и что с этого будет в итоге ? своя обвертка для 1с или че ?
34 oleg_km
 
10.05.13
19:55
В общем сделал вот так:

public object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)

...

          object obj;
           if (T.IsEnum)
               obj = Enum.Parse(T, name);
           else
           {
               if (isType)
                   obj = T.InvokeMember(name, invokeAttr, binder, null, args, modifiers, culture, namedParameters);
               else
                   obj = T.InvokeMember(name, invokeAttr, binder, O, args, modifiers, culture, namedParameters);
           }

Т.е. нужное мне вариант перечисления парсится. Вызов как шарпе:

       ТипАдрес = объект.GetTypeByStr("System.Net.Sockets.AddressFamily, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "");
Сообщить(ТипАдрес.InterNetwork.ToString());

Только у перечисления так же есть методы, которые нужно пропустить в Invoke. Подскажи, как invokeAttr протестировать на наличие флага InvokeMethod, элементарщину пропустил на сях?
35 oleg_km
 
10.05.13
20:04
Вот так пока сделал условие:

if (T.IsEnum && !invokeAttr.HasFlag(BindingFlags.InvokeMethod))
36 oleg_km
 
10.05.13
20:28
Ура, работает:

   объект = Новый COMОбъект("NetObjectToIDispatch");
   Активатор = объект.Activator;
   
   Если Ложь Тогда
       //Типмд5 = объект.GetTypeByStr("System.Security.Cryptography.MD5CryptoServiceProvider", "");
       //мд5 = Активатор.CreateInstance(Типмд5);

       мд5 = объект.CreateObject("System.Security.Cryptography.MD5CryptoServiceProvider");

       типЭнкодинг = объект.GetTypeByStr("System.Text.Encoding","");
       мсДанные = типЭнкодинг.Default.GetBytes("Строка");

       рез = мд5.ComputeHash(мсДанные);
//        Сообщить(типЭнкодинг.Default.GetString(рез));
       
       Для ии = 0 По рез.Length - 1 Цикл
           Сообщить(рез.GetValue(ии));
       КонецЦикла;
   КонецЕсли;    

   Если Ложь Тогда
       ТипПорт = объект.GetTypeByStr("System.IO.Ports.SerialPort, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "");
       обПорт = Активатор.CreateInstance(ТипПорт);
       
       обПорт.PortName = "COM43";
       обПорт.BaudRate = 115200;
       обПорт.ReadTimeout = 500;
       обПорт.Open();
       
       обПорт.Write("AT" + Символы.ВК);
       Слееп = объект.GetTypeByStr("System.Threading.Thread", "");
       Слееп.Sleep(1000);
       Сообщить(обПорт.ReadExisting());
       
       обПорт.Close();
   КонецЕсли;    
   
   Если Истина Тогда
       ТипСокет = объект.GetTypeByStr("System.Net.Sockets.Socket, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "");
       ТипАдрес = объект.GetTypeByStr("System.Net.Sockets.AddressFamily, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "");
       ТипТип = объект.GetTypeByStr("System.Net.Sockets.SocketType, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "");
       ТипПротокол = объект.GetTypeByStr("System.Net.Sockets.ProtocolType, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "");
       
       мсПарам = объект.CreateArray("System.Object", 3);
       мсПарам.SetValue(ТипАдрес.InterNetwork, 0);
       мсПарам.SetValue(ТипТип.Stream, 1);
       мсПарам.SetValue(ТипПротокол.Tcp, 2);
       
       обСокет = Активатор.CreateInstance(ТипСокет, мсПарам);
       обСокет.Connect("smtp.mail.ru", 25);
       
       Слееп = объект.GetTypeByStr("System.Threading.Thread", "");
       Слееп.Sleep(200);
       
       мсРез = объект.CreateArray("System.Byte", обСокет.Available);
       обСокет.Receive(мсРез);
       типЭнкодинг = объект.GetTypeByStr("System.Text.Encoding","");
       Сообщить("1: " + типЭнкодинг.Default.GetString(мсРез));
       
       мсДанные = типЭнкодинг.Default.GetBytes("QUIT" + Символы.ВК + Символы.ПС);
       обСокет.Send(мсДанные);
       
       Слееп = объект.GetTypeByStr("System.Threading.Thread", "");
       Слееп.Sleep(200);
       
       мсРез = объект.CreateArray("System.Byte", обСокет.Available);
       обСокет.Receive(мсРез);
       типЭнкодинг = объект.GetTypeByStr("System.Text.Encoding","");
       Сообщить("2: " + типЭнкодинг.Default.GetString(мсРез));
       
       ТипЗакрытие = объект.GetTypeByStr("System.Net.Sockets.SocketShutdown, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "");
       обСокет.ShutDown(ТипЗакрытие.Both);
       обСокет.Close();
   КонецЕсли;
37 Serginio1
 
10.05.13
21:48
Отлично. Но надо еще добить Type в параметрах. см 32
38 oleg_km
 
10.05.13
22:29
(37) А это для каких случаев нужно? Надышался бензина и краски и что-то голова уже не соображает
39 Serginio1
 
10.05.13
23:39
38 А то что у тебя в 24 не получалось.
40 Serginio1
 
10.05.13
23:47
39 + То что в 32 для парпметров
if (args[x].ЭтоТип)
args[x] = ((AutoWrap)args[x]).T
41 oleg_km
 
11.05.13
08:24
(40) Да понял, добавлю. Это для случая, если мою ссылку на тип нужно будет передать параметром в метод? Так ведь без разницы что передавать, что O что T. Для типа O == T включая тип
42 Serginio1
 
11.05.13
10:28
По идее да. Я просто не понял, что у тебя в 24 не получилось.
Просто помню с типом боролся, а что и почему уже не помню.
По идее
public object ПолучитьПеречисление(Type Тип, string Предствление)
{
 return new AutoWrap(Enum.Parse(Тип, Представление);
}
должен проходить
43 oleg_km
 
11.05.13
11:37
(42)
public object ПолучитьПеречисление(Type Тип, string Предствление)

{
 return new AutoWrap(Enum.Parse(Тип, Представление);
}
должен проходить


Это лишнее, лучше как в (34) дополнить public object InvokeMember, чтобы он как шарпе давал выбирать перечисление через точку

У меня теперь другая проблема, под 4.0 работает, а хотелось бы под 3.5. Но там ругается не могу загрузить сборку. Позже поразбираюсь - напишу подробности.
44 Serginio1
 
11.05.13
11:52
Я не про перечисления. Почему у тебя в 24
а вот какой тип должен иметь Тип. Если Type, то падает в момент вызова неизвестная ошибка, если объект, то падает при приведении

А вот для 3.5 нужно и компилировать под 3.5 и соответственно в версию другую указывать не 4.0.0.0
ТипСокет = объект.GetTypeByStr("System.Net.Sockets.Socket, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "");
45 oleg_km
 
11.05.13
13:17
Я наоборот класс NetObjectToIDispatch максимально разгрузил, оставил только

public object GetTypeByStr(string type)
{ return new AutoWrap(Type.GetType(type, true)); }

из него можно все получить и активатор и конструктор массивов:

объект = Новый COMОбъект("1CAddInNET.NET2COM");
Активатор = объект.GetTypeByStr("System.Activator");

ТипСборки = объект.GetTypeByStr("System.Reflection.Assembly");
Сборка = ТипСборки.Load("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");

ТипОбъект = объект.GetTypeByStr("System.Object");
ТипМассив = объект.GetTypeByStr("System.Array");
       
мсПарам = ТипМассив.CreateInstance(ТипОбъект, 3);
мсПарам.SetValue(ТипАдрес.InterNetwork, 0);
мсПарам.SetValue(ТипТип.Stream, 1);
мсПарам.SetValue(ТипПротокол.Tcp, 2);
       
обСокет = Активатор.CreateInstance(ТипСокет, мсПарам);
обСокет.Connect("smtp.mail.ru", 25);
46 Serginio1
 
11.05.13
13:37
Да я непомню уже для чего добавлял методы. Но например

public object ВыполнитьМетод(object obj,string ИмяМетода)
       {
           if (obj is AutoWrap)
           obj=((AutoWrap)obj).O;
           Type T=obj.GetType();
           
             
             
         return  new AutoWrap(T.InvokeMember(ИмяМетода,BindingFlags.DeclaredOnly |
           BindingFlags.Public | BindingFlags.NonPublic |
           BindingFlags.Instance | BindingFlags.InvokeMethod, null, obj, null));
       }
   }

Специально добавил так как не выполнялся метод ToArray для дженериковского листа не проходил
Активатором проще изначальнопользоваться.
Масиивом тоже.
http://rsdn.ru/forum/dotnet/4320177

public object ПолучитьИнтерфейс(object obj, string InterfaseName)
       {

      if (obj is AutoWrap)
           obj=((AutoWrap)obj).O;

      Type type = obj.GetType().GetInterface(InterfaseName, true);
      return new AutoWrap(obj, type);
       }
47 Serginio1
 
11.05.13
13:38
И соответственно 3 конструктора
public AutoWrap() { }
       public AutoWrap(object obj)
       {
           O = obj;
           if (O is Type)
           {
               T = O as Type;
               ЭтоТип = true;
           }
           else {
               T = O.GetType();
               ЭтоТип = false;
           }
           
       }
       public AutoWrap(object obj, Type type)
       {
           O = obj;
           T = type;
           ЭтоТип = false;
         
           
       }
48 oleg_km
 
11.05.13
14:15
Ладно, нужно пробовать. Чуствую, что для полного счастья делегаты еще нужны.
49 Serginio1
 
11.05.13
14:19
(48) Нужно смотреть в сторону DynamicAssembly и генерации кода
например

http://www.rsdn.ru/forum/src/3165397.1
50 Serginio1
 
11.05.13
14:25
Или посмотреть CodeDOM
http://msdn.microsoft.com/ru-ru/library/ms404245.aspx
51 oleg_km
 
11.05.13
14:36
(49)(50) Мда, это по-любому будет означать четверку. В принципе невелика печаль.
52 Serginio1
 
11.05.13
14:40
(48) Вообще я эту обертку испольую для простого использования готовых классов. Например для доступа к Вэб сервисам, в тех случаях когда 1С их не понимает. Отдельно описывать все методы через Оле оберку нет смысла когда методов под сотню. И для этих случаев обертка через IReflect самое то. Для использования более специальных обработок проще использовать уже COM классы. Например Внешняя компонента .NET
53 Serginio1
 
11.05.13
14:46
Кстати а DR я использую через http://1c.proclub.ru/modules/mydownloads/personal.php?cid=115&lid=2019

Просто пишу COM объект добавляю метод  void InitFrom1C(object Object1C);
И все

public void InitFrom1C(object Object1C)
       {
     //      MessageBox.Show("InitFrom1C");
           try
           {
               Event = new AutoResetEvent(false);

               EventTo1C = Object1C as IAsyncEvent;




               SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());
               Sc = SynchronizationContext.Current;
           }
           catch (Exception e)
           {
               MessageBox.Show(e.ToString());
               throw e;

           }
         
           
       
       }
54 oleg_km
 
11.05.13
15:44
(52) Да я вот тоже, начал писать обертку, вернее у меня есть на С++. Решил переделать на шарп и не хочется все писать на шарпе. Я думаю, где нужны будут события, буду делать спец. обертки, где просто синхронные функции - пользовать универсальную обертку
55 Serginio1
 
11.05.13
20:07
Вообще IReflect нужный инструмент. И его легко использовать. Только почему то не очень используемый. Хотя рыбу я взял у писателей сайтов.
Кстати нечто аналогичное на уровне динамиков можно делать и для Net через IDynamicObject
http://intellitect.com/dynamically-typed-objects-with-c-4-0/
56 Serginio1
 
21.05.13
11:48
(48) Блин сам забыл
System.Delegate.CreateDelegate

http://msdn.microsoft.com/en-us/library/system.delegate.createdelegate.aspx
57 Serginio1
 
21.05.13
11:52
А тип делегата можно получить так http://www.rsdn.ru/forum/dotnet/5174968.1
58 oleg_km
 
21.05.13
12:24
(56)(57) Если бы еще понять как это приспособить. У меня задача такая. С помощью вышеупомянутой обертки например сделал работу с сокетом и ком-портов в синхронном режиме. Но мне кроме того нужно ее и в асинхронном, вернее нужно чтобы в 1С поступали события по аналогии с активИкс. Если можешь накидать простенький пример, как допустим классу SelialPort назначить событие DataReceived, не обязательно работающий пример, можно просто набросок? Не владею глубоко дотНетом, чтобы разобраться
59 Serginio1
 
21.05.13
12:49
Тебе нужно ВК писать например

public void InitFrom1C(object Object1C)
       {
           try
           {
               Event = new AutoResetEvent(false);

               EventTo1C = Object1C as IAsyncEvent;
SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());
               Sc = SynchronizationContext.Current;
           }
           catch (Exception e)
           {
               MessageBox.Show(e.ToString());
               throw e;

           }
         
           

       }


public void ОткрытьАйПиПорт()
       {
           
       //    Trace.WriteLine(DateTime.Now.ToString() + " - InitFrom1C " + ИдПотока.ToString());
       //    Trace.Flush();
           ОткрытьАйПиПортСНомеромПорта(6891);
       }

       public void ОткрытьАйПиПортСНомеромПорта(int НомерПорта)
       {

 
           Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
           IPEndPoint ipEndpoint = new IPEndPoint(IPAddress.Any, НомерПорта);
           Server.Bind(ipEndpoint);
           Server.Listen(1);
           Server.BeginAccept(new AsyncCallback(ОбработкаСоединения), Server);
       
       }

Где
       private void ОбработкаСоединения(IAsyncResult AsyncCall)
       {
         Socket listener = (Socket)AsyncCall.AsyncState;
         if (listener == null || (ЭтоЗакрытие)) return;

         Socket client = listener.EndAccept(AsyncCall);
          ВыполнитьКоманду(client);
                 // После того как завершили соединение, говорим ОС что мы готовы принять новое
         listener.BeginAccept(new AsyncCallback(ОбработкаСоединения), listener);  
       }


private void ВыполнитьКоманду(Socket client)
       {

                NetworkStream стрим=new NetworkStream(client);
       bool ЕстьОтвет;
       try
       {
           
                       ДляОбменаПоТСП.ПринятьКоманду(стрим, out команда, out данныеДляКоманды, out ЕстьОтвет);
         

           Event.Reset();
           Sc.Send(d => ExternalEvent1С(), null);
         
           if (ЕстьОтвет)
           {
               Event.WaitOne();
               ДляОбменаПоТСП.WriteCompressedString(стрим, Otvet);


           }
       }
       catch (Exception e)
       {
           ЗаписатьОшибку(DateTime.Now.ToString() + e.ToString());
           
       }
       }
60 Serginio1
 
21.05.13
12:57
void ExternalEvent1С()
       {
           try
           {
                               EventTo1C.SetEventBufferDepth(4096);
               EventTo1C.ExternalEvent("ДанныеПоTCP", "Команда", "");
           
           }
       catch (Exception e)
       {
           ЗаписатьОшибку(DateTime.Now.ToString() + e.ToString());
         
       }
       
       }

Из 1С доступ к данным через свойство
public string ДанныеДляКоманды{get{return данныеДляКоманды;}}
так как есть ограничение на строку во третьем  параметре.
Хотя можно побороть с помощью SetEventBufferDepth но проще доступ из 1С к свойству
61 Serginio1
 
21.05.13
12:59
Ну и соответственно если есть ответ
public void Ответить(string Ответ)
       {
           Otvet = Ответ;
           Event.Set();
       
       }
62 oleg_km
 
21.05.13
13:43
(60)-(62) Да нет так я могу написать и активикс. Мне хочется не писаь код шарпе, а весь код писать в 1С, например:

Процедура TCPServerНажатие(Элемент)
   обСокет = Плагин.СоздатьОбъект(Плагин.ПолучитьТип("System.Net.Sockets.Socket", "System"),
       Плагин.ПолучитьТип("System.Net.Sockets.AddressFamily", "System").InterNetwork,
       Плагин.ПолучитьТип("System.Net.Sockets.SocketType", "System").Stream,
       Плагин.ПолучитьТип("System.Net.Sockets.ProtocolType", "System").Tcp);
       
//    Точка = Плагин.СоздатьОбъект(Плагин.ПолучитьТип("System.Net.IPEndPoint", "System"),
//        Плагин.ПолучитьТип("System.Net.IPAddress", "System").Any, 9000);
   Точка = Плагин.СоздатьОбъект(Плагин.ПолучитьТип("System.Net.IPEndPoint", "System"),
       0, 9000);
   обСокет.Bind(Точка);
   обСокет.Listen(10);

   ТипСобытия = Плагин.ПолучитьТип("System.Net.Sockets.SelectMode", "System");
   Для ии = 1 По 10 Цикл
       Сообщить("Ожидание: " + Число2Стр(ии));
       
       Рез = обСокет.Poll(10 * 1000000, ТипСобытия.SelectRead);
       Если НЕ Рез Тогда
           Сообщить(Символы.Таб + "Тайм аут подключения");
           Продолжить;
       КонецЕсли;
       
       обНовыйСокет = обСокет.Accept();
       Сообщить(Символы.Таб + "Соединение: " +
           обНовыйСокет.LocalEndPoint.Address.ToString() + "/" + Число2Стр(обНовыйСокет.LocalEndPoint.Port) + " => " +
           обНовыйСокет.RemoteEndPoint.Address.ToString() + "/" + Число2Стр(обНовыйСокет.RemoteEndPoint.Port));
       
       мсДанные = Плагин.ПолучитьТип("System.Text.Encoding").Default.GetBytes("Hello:" + Символы.ВК + Символы.ПС);
       обНовыйСокет.Send(мсДанные);
       
       Рез = обНовыйСокет.Poll(10 * 1000000, ТипСобытия.SelectRead);
       Если Рез Тогда
           мсРез = Плагин.СоздатьМассив(Плагин.ПолучитьТип("System.Byte"), обНовыйСокет.Available);
           обНовыйСокет.Receive(мсРез);
           Сообщить(Символы.Таб + "Принято: " + Плагин.ПолучитьТип("System.Text.Encoding").Default.GetString(мсРез));
       КонецЕсли;
       
       Сообщить(Символы.Таб + "Закрываю");
       обНовыйСокет.ShutDown(Плагин.ПолучитьТип("System.Net.Sockets.SocketShutdown", "System").Both);
       обНовыйСокет.Close();
   КонецЦикла;

//    обСокет.ShutDown(Плагин.ПолучитьТип("System.Net.Sockets.SocketShutdown", "System").Both);
   обСокет.Close();
КонецПроцедуры


Вот, весь код написан в 1С, не нужно обновлять сборку, перераспространять ее. Один раз установить класс-обертку, а дальше все на стороне 1С. Вот еще добавить как-то создание делегата на базе метода объекта 1С (?) и функцию установить этот делегат событию нужного объекта. Это вообще возможно? Мой уровень познания шарпа не дает возможности оценить.
63 Serginio1
 
21.05.13
13:55
(62) Только на обНовыйСокет.Poll 1С будет заморожена.
Все же сервер должен работать в ассинхронном режиме.

можешь попробовать события
http://stackoverflow.com/questions/10052722/manage-activex-net-event-by-javascript
64 Serginio1
 
21.05.13
14:01
(62) Ты можешь передать в свою библиотеку общий модуль.
Например

На Шарпе есть Свойство dinamic Модуль1С {get;set;}
Из 1С установи это свойство.
ШарпОбъект.Модуль1С=ОбщегоНазначения;

Из Шарпа вызывай Модуль1С.ВнешнееСобытие()

Метод ВнешнееСобытие должен быть в модуле ОбщегоНазначения
65 oleg_km
 
21.05.13
14:06
(63)(64) Это мне все понятно, это я уже делал. Но это предполагает необходимость написания кода как в конфигурации 1С, так и в проекте на шарпе. Я же хочу, чтобы проект на шарпе был просто универсальной оберткой и больше не менялся, а весь нужный код, в том числе и дотнетный дописывался на 1С, как (62).
66 Serginio1
 
21.05.13
14:20
(65) А зачем так извращаться то? Сом библиотеку легче написать.

Эта обертка хороша для готового класса с использованием кучей классов не использующих ComVisible = true.
67 Serginio1
 
21.05.13
14:24
Даже так AutoWrap больше нужен внутри Net что бы выдавать на сторону 1С Idispatch обертку.
68 Serginio1
 
21.05.13
14:28
Для делегатов можешь использовать свой сборки с классами специально сгенеренными под задачу, но будет ничем не лучше создания Com библиотеки
69 oleg_km
 
21.05.13
14:32
(67) Ну я просто хотел решить организационную задачу: развивать проект, только на стороне кода 1С. А в шарп не лазить вообще. Написать суперуниверсальную обертку и дальше кодить на стороне 1С. Ну нет, так нет. Все равно еще нужно обращение к DLLImport. Поэтому решил для событий сделаю специализированные актисИскы, для DLLImport сделаю спецклассы, все остальное буду дергать через обертку. Всяко легче будет
70 Serginio1
 
21.05.13
15:03
(69) Ну можешь конечно посмотреть в сторону CSharpCodeProvider

http://www.gotdotnet.ru/blogs/olegaxenow/6520
http://msdn.microsoft.com/en-us/library/microsoft.csharp.csharpcodeprovider.aspx

Но это опять ничем не будет лучше чисто нетовских сборок.
Но я никак не вижу премущества перед Сом объектом. Но тут уж хозяин барин.