问题描述
我有一个类:
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例外集(代表德尔)。有没有更好的方式来转发委托作为参数?或者,我做了一些错误,在这里,我没有看到。什么是我想要做的是someInterface.SetText通过此方法的参数。感谢您的帮助。
And I get targetinvocation exception in Set(Delegate del). Is there a better way to forward delegate as parameter? Or I making some mistake here that I not seeing. What am I trying to do is to pass someInterface.SetText this method as parameter. Thanks for helping.
推荐答案
以下工作:
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
,下面的工作了:
Next, if you're looking to pass a callback function from C++ to Icom.Set
, the following would work too:
[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");
}
}
请确保32位code编译您的两个C#和C ++项目。 C ++的回调函数应该被声明为:
Make sure to compile both of your C# and C++ projects as 32-bit code. The C++ callback function should be declared as such:
static HRESULT __stdcall SetTextDelCallback(BSTR value)
{
return S_OK;
}
最后,正确的方式来实现这个,国际海事组织,是简单地定义一个回调接口(如 ISetCallback
以下),传递对象实现这样的接口,而不是委托。 ISetCallback
可以用任何语言来实现,C#或C ++:
Finally, the proper way to implement this, IMO, is to simply define a callback interface (like ISetCallback
below) and pass an object implementing such interface, rather than a delegate. ISetCallback
can be implemented in any language, either C# or 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);
}
这篇关于是否有可能通过COM互操作转发的委托?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!