gpt4 book ai didi

c# - 是否可以通过 COM 互操作转发委托(delegate)?

转载 作者:行者123 更新时间:2023-12-03 22:56:11 25 4
gpt4 key购买 nike

我有一个类:

public class A
{
public delegate void SetTextDel(string value);
public void Test()
{
SetTextDel setText = someInterface.SetText;
icom.Set(setText);
}
}

[ComVisible(true), Guid("81C99F84-AA95-41A5-868E-62FAC8FAC263"), InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface Icom
{
void Set(Delegate del);
}

[ComVisible(true)]
[Guid("6DF6B926-8EB1-4333-827F-DD814B868097")]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(Icom))]
public class B : Icom
{
Set(Delegate del)
{
del.DynamicInvoke("some text");
}
}

然后我在 Set(Delegate del) 中得到了 targetinvocation 异常。有没有更好的方法将委托(delegate)作为参数转发?或者我在这里犯了一些我没有看到的错误。我想做的是将 someInterface.SetText 这个方法作为参数传递。感谢您的帮助。

最佳答案

以下作品:

public class A
{
public delegate void SetTextDel(string value);

void TestSetText(string value)
{
MessageBox.Show(value);
}

public void Test(Icom icom)
{
SetTextDel del = TestSetText;
icom.Set(del);
}
}

[ComVisible(true), Guid("81C99F84-AA95-41A5-868E-62FAC8FAC263"), InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface Icom
{
void Set(Delegate del);
}

[ComVisible(true)]
[Guid("6DF6B926-8EB1-4333-827F-DD814B868097")]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(Icom))]
public class B : Icom
{
public void Set(Delegate del)
{
del.DynamicInvoke("some text");
}
}

private void buttonTest_Click(object sender, EventArgs e)
{
var a = new A();
var b = new B();

a.Test(b);
}

接下来,如果您希望将回调函数从 C++ 传递Icom.Set,以下方法也可以:

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void SetTextDel([MarshalAs(UnmanagedType.BStr)] string value);

[ComVisible(true), Guid("81C99F84-AA95-41A5-868E-62FAC8FAC263"), InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface Icom
{
void Set([MarshalAs(UnmanagedType.FunctionPtr)] SetTextDel del);
}

[ComVisible(true)]
[Guid("6DF6B926-8EB1-4333-827F-DD814B868097")]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(Icom))]
public class B : Icom
{
public void Set(SetTextDel del)
{
del("some text");
}
}

确保将 C# 和 C++ 项目都编译为 32 位代码。 C++ 回调函数应该这样声明:

static HRESULT __stdcall SetTextDelCallback(BSTR value)
{
return S_OK;
}

最后,实现这个的正确方法,IMO,是简单地定义一个回调接口(interface)(像下面的ISetCallback)并传递一个实现这个接口(interface)的对象,而不是一个代表。 ISetCallback 可以用任何语言实现,C# 或 C++:

[ComVisible(true), Guid("2FE5D78D-D9F2-4236-9626-226356BA25E7")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ISetCallback
{
void OnSetText(string value);
}

public class A : ISetCallback
{
public void OnSetText(string value) // ISetCallback
{
MessageBox.Show(value);
}

public void Test(Icom icom)
{
icom.Set(this);
}
}

[ComVisible(true), Guid("81C99F84-AA95-41A5-868E-62FAC8FAC263"), InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface Icom
{
void Set(ISetCallback callback);
}

[ComVisible(true)]
[Guid("6DF6B926-8EB1-4333-827F-DD814B868097")]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(Icom))]
public class B : Icom
{
public void Set(ISetCallback callback)
{
callback.OnSetText("some text");
}
}

private void buttonTest_Click(object sender, EventArgs e)
{
var a = new A();
var b = new B();

a.Test(b);
}

关于c# - 是否可以通过 COM 互操作转发委托(delegate)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19034762/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com