Сообщение Re[90]: Java vs C# vs C++ от 11.10.2015 21:08
Изменено 11.10.2015 21:33 Serginio1
Здравствуйте, -MyXa-, Вы писали:
MX>Здравствуйте, Serginio1, Вы писали:
S>>
MX>Дай угадаю, "[DISPID=-4]" — это С-шный
MX>
Это запрос комовского Энумератора.
MX>Это ты придумал со строкой сравнивать, или это работа мастера?
Это нетовская работа с диспинтерфейсами. Обычно Кроме инвоке идут GetIDsOfNames
MX>Но, вообще, это не код, это... короче, C# — ассемблер современности.
MX>Ты уверен, что как ты написал — так это и должно делаться?
Это используется уже кучу лет.
MX>На Visual C++ ты напишешь типа того:
MX>
MX>А при твоём подходе события поддерживаются? События — такая же стандартная фича, как и IDispatch (см. IConnectionPoint и атрибут event_source).
MX>И если ты всё руками делаешь — tlb откуда возьмётся?
А зачем tlb? Есть ITypeInfo котрый и реализуется во врапере методы IReflect. Да и Idispatch и он не нужен. 1С прекрасно без него обходится
Со свойствами проблема, но их можно динамически обернуть. То есть сделать обертку над классом для описания свойв.
Для простых случаев можно так.
Либо пишу ручками используя анонимные типы. И подписка
MX>Здравствуйте, Serginio1, Вы писали:
S>>
S>> public object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] argsOrig, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
S>> { // Unwrap any AutoWrap'd objects (they need to be raw if a paramater)
S>> if (name == "[DISPID=-4]")
S>> {
S>> return new EnumVariantImpl(((IEnumerable)O).GetEnumerator());
S>> }
MX> [поскипана куча]
S>>
MX>Дай угадаю, "[DISPID=-4]" — это С-шный
MX>
MX>#define DISPID_NEWENUM ( -4 )
MX>
Это запрос комовского Энумератора.
MX>Это ты придумал со строкой сравнивать, или это работа мастера?
Это нетовская работа с диспинтерфейсами. Обычно Кроме инвоке идут GetIDsOfNames
MX>Но, вообще, это не код, это... короче, C# — ассемблер современности.
MX>Ты уверен, что как ты написал — так это и должно делаться?
Это используется уже кучу лет.
MX>На Visual C++ ты напишешь типа того:
MX>
MX>[
MX> object,
MX> dual // Это разрешает поддержку IDispatch
MX>]
MX>interface MyInterface
MX>{
MX> // твои методы
MX>};
MX>[
MX> coclass,
MX> default(MyInterface)
MX>]
MX>class MyClass
MX>{
MX> // реализации методов
MX>};
MX>
MX>А при твоём подходе события поддерживаются? События — такая же стандартная фича, как и IDispatch (см. IConnectionPoint и атрибут event_source).
MX>И если ты всё руками делаешь — tlb откуда возьмётся?
А зачем tlb? Есть ITypeInfo котрый и реализуется во врапере методы IReflect. Да и Idispatch и он не нужен. 1С прекрасно без него обходится
Со свойствами проблема, но их можно динамически обернуть. То есть сделать обертку над классом для описания свойв.
Для простых случаев можно так.
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
// [Guid("33B45C9D-1AED-41F9-8880-36AB6AE84749")]
public interface IEventFor1C
{
[DispId(0x60020000)]
void Событие();
[DispId(0x60020001)]
void СобытиеСПараметром(object value);
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[Guid("62F8156C-13B9-4484-B152-82023243E1D3")]
[ComSourceInterfaces(typeof(IEventFor1C))]
public class ClassForEvent1C
{
[ComVisible(false)]
public delegate void Событие_Delgate();
public delegate void СобытиеСПараметром_Delgate(object value);
public object Объект;
private SynchronizationContext Sc;
public ClassForEvent1C(object Объект,String СобытиеОбъекта,bool ЕстьПараметр=false)
{
this.Объект = Объект;
BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
EventInfo ei = Объект.GetType().GetEvent(СобытиеОбъекта, bf);
if (!ЕстьПараметр)
ei.AddEventHandler(Объект, new System.Action(ВнешнееСобытие));
else
ei.AddEventHandler(Объект, new System.Action<object>(ВнешнееСобытиеСПараметром));
SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());
Sc = SynchronizationContext.Current;
}
public event Событие_Delgate Событие;
public event СобытиеСПараметром_Delgate СобытиеСПараметром;
private void ВнешнееСобытие()
{
if (this.Событие != null) //Событие();
Sc.Send(d => Событие(), null);
}
private void ВнешнееСобытиеСПараметром(object value)
{
if (this.СобытиеСПараметром != null) //Событие();
Sc.Send(d => СобытиеСПараметром(AutoWrap.ОбернутьОбъект(value)), null);
}
}
Либо пишу ручками используя анонимные типы. И подписка
void OnGetMessageImage(object value);
wa.OnGetMessageImage += (mediaNode, from, id, fileName, fileSize, url, preview) =>
{
ОтослатьСобытиеСПараметром(OnGetMessageImage, new { mediaNode = mediaNode, from = from, id = id, fileName = fileName, fileSize = fileSize, url = url, preview = preview }, "OnGetMessageImage");
};
Re[90]: Java vs C# vs C++
Здравствуйте, -MyXa-, Вы писали:
MX>Здравствуйте, Serginio1, Вы писали:
S>>
MX>Дай угадаю, "[DISPID=-4]" — это С-шный
MX>
Это запрос комовского Энумератора.
MX>Это ты придумал со строкой сравнивать, или это работа мастера?
Это нетовская работа с диспинтерфейсами. Обычно Кроме инвоке идут GetIDsOfNames
MX>Но, вообще, это не код, это... короче, C# — ассемблер современности.
MX>Ты уверен, что как ты написал — так это и должно делаться?
Это используется уже кучу лет.
MX>На Visual C++ ты напишешь типа того:
MX>
MX>А при твоём подходе события поддерживаются? События — такая же стандартная фича, как и IDispatch (см. IConnectionPoint и атрибут event_source).
MX>И если ты всё руками делаешь — tlb откуда возьмётся?
А зачем tlb? Есть ITypeInfo котрый и реализуется во врапере методы IReflect. Да и Idispatch и он не нужен. 1С прекрасно без него обходится
Со свойствами проблема, но их можно динамически обернуть. То есть сделать обертку над классом для описания свойв.
Для простых случаев можно так.
Либо пишу ручками используя анонимные типы. И подписка
Да и приходится для Событий работать с реальным объектом
MX>Здравствуйте, Serginio1, Вы писали:
S>>
S>> public object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] argsOrig, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
S>> { // Unwrap any AutoWrap'd objects (they need to be raw if a paramater)
S>> if (name == "[DISPID=-4]")
S>> {
S>> return new EnumVariantImpl(((IEnumerable)O).GetEnumerator());
S>> }
MX> [поскипана куча]
S>>
MX>Дай угадаю, "[DISPID=-4]" — это С-шный
MX>
MX>#define DISPID_NEWENUM ( -4 )
MX>
Это запрос комовского Энумератора.
MX>Это ты придумал со строкой сравнивать, или это работа мастера?
Это нетовская работа с диспинтерфейсами. Обычно Кроме инвоке идут GetIDsOfNames
MX>Но, вообще, это не код, это... короче, C# — ассемблер современности.
MX>Ты уверен, что как ты написал — так это и должно делаться?
Это используется уже кучу лет.
MX>На Visual C++ ты напишешь типа того:
MX>
MX>[
MX> object,
MX> dual // Это разрешает поддержку IDispatch
MX>]
MX>interface MyInterface
MX>{
MX> // твои методы
MX>};
MX>[
MX> coclass,
MX> default(MyInterface)
MX>]
MX>class MyClass
MX>{
MX> // реализации методов
MX>};
MX>
MX>А при твоём подходе события поддерживаются? События — такая же стандартная фича, как и IDispatch (см. IConnectionPoint и атрибут event_source).
MX>И если ты всё руками делаешь — tlb откуда возьмётся?
А зачем tlb? Есть ITypeInfo котрый и реализуется во врапере методы IReflect. Да и Idispatch и он не нужен. 1С прекрасно без него обходится
Со свойствами проблема, но их можно динамически обернуть. То есть сделать обертку над классом для описания свойв.
Для простых случаев можно так.
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
// [Guid("33B45C9D-1AED-41F9-8880-36AB6AE84749")]
public interface IEventFor1C
{
[DispId(0x60020000)]
void Событие();
[DispId(0x60020001)]
void СобытиеСПараметром(object value);
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[Guid("62F8156C-13B9-4484-B152-82023243E1D3")]
[ComSourceInterfaces(typeof(IEventFor1C))]
public class ClassForEvent1C
{
[ComVisible(false)]
public delegate void Событие_Delgate();
public delegate void СобытиеСПараметром_Delgate(object value);
public object Объект;
private SynchronizationContext Sc;
public ClassForEvent1C(object Объект,String СобытиеОбъекта,bool ЕстьПараметр=false)
{
this.Объект = Объект;
BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
EventInfo ei = Объект.GetType().GetEvent(СобытиеОбъекта, bf);
if (!ЕстьПараметр)
ei.AddEventHandler(Объект, new System.Action(ВнешнееСобытие));
else
ei.AddEventHandler(Объект, new System.Action<object>(ВнешнееСобытиеСПараметром));
SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());
Sc = SynchronizationContext.Current;
}
public event Событие_Delgate Событие;
public event СобытиеСПараметром_Delgate СобытиеСПараметром;
private void ВнешнееСобытие()
{
if (this.Событие != null) //Событие();
Sc.Send(d => Событие(), null);
}
private void ВнешнееСобытиеСПараметром(object value)
{
if (this.СобытиеСПараметром != null) //Событие();
Sc.Send(d => СобытиеСПараметром(AutoWrap.ОбернутьОбъект(value)), null);
}
}
Либо пишу ручками используя анонимные типы. И подписка
void OnGetMessageImage(object value);
wa.OnGetMessageImage += (mediaNode, from, id, fileName, fileSize, url, preview) =>
{
ОтослатьСобытиеСПараметром(OnGetMessageImage, new { mediaNode = mediaNode, from = from, id = id, fileName = fileName, fileSize = fileSize, url = url, preview = preview }, "OnGetMessageImage");
};
Да и приходится для Событий работать с реальным объектом
whatsappFor1C=Сборка.GetType("whatsappFor1C.whatsappFor1C");
ВАОбертка=врап.СоздатьОбъект(whatsappFor1C,врап,Телефон,Пароль,Ник);
СтатусСоединения=Врап.ПолучитьТип("WhatsAppApi.ApiBase+CONNECTION_STATUS");
wa=ВАОбертка.wa;
ВА=Врап.ПолучитьРеальныйОбъект(ВАОбертка);
ДобавитьОбработчик Ва.OnConnectFailed, ПриОшибкеСоединения;
ДобавитьОбработчик Ва.OnConnectSuccess, ПриУспешномСоединении;