C# 是否可以通过COM互操作转发委托?
我有一门课:C# 是否可以通过COM互操作转发委托?,c#,.net,visual-studio-2012,com,com-interop,C#,.net,Visual Studio 2012,Com,Com Interop,我有一门课: 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"), InterfaceTy
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");
}
}
我在集合中得到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实现该接口的正确方法是简单地定义一个回调接口(如下面的ISetCallback
),并传递一个实现该接口的对象,而不是委托ISetCallback
可以用任何语言实现,无论是C#还是C++:
这段代码有效吗?是的,COM正在被识别,这只是一个简短的版本。我只需要帮助将委托作为参数传递给B类。你是个天才。非常感谢。没问题,很高兴能帮上忙。
[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);
}