是否可以通过COM互操作转发代表?

我上课了:

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)中获得了targetinvocationexception。 有没有更好的方法来转发委托作为参数? 或者我在这里犯了一些我没有看到的错误。 我想做的是将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 ++:

 [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); }