Сообщение Re[90]: Java vs C# vs C++ от 11.10.2015 21:08
Изменено 11.10.2015 21:12 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 откуда возьмётся?
Со свойствами проблема, но их можно динамически обернуть. То есть сделать обертку над классом для описания свойв.
Для простых случаев можно так.
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 откуда возьмётся?
Со свойствами проблема, но их можно динамически обернуть. То есть сделать обертку над классом для описания свойв.
Для простых случаев можно так.
[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);
}
}
Здравствуйте, -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? Tcnm ITypeInfo. Да и 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? Tcnm ITypeInfo. Да и 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);
}
}