我有一个用C#编写的.dll
,我在Visual Basic中使用它来制作一个Com对象。我从我的Visual Basic代码中调用C#函数。我对这项技术很陌生,遇到了这样的问题。在C#代码中,我有一个方法,它接收一个回调函数作为参数,从服务器获取数据然后调用该回调函数。现在我需要从我的Visual Basic代码中调用该函数并向其传递回调。
我认为应该看起来像这样
// C# dll
public bool GetDataFromServer(int someData1, Action<MyCustomType> callback, int someData2)
{
// request to server, get data, create an object of MyCustomType
// call callback and pass MyCustomType object to it as a parameter
}
// Visual Basic part
Public Sub DisplayData(ByRef resp As My_Dll.MyCustomType)
' do something with resp
End Sub
// call Dll method
My_Dll.GetDataFromServer(1, DisplayData, 2) ' I get a compile error
但我无法让它工作,事件无法编译。我收到一个编译错误,说&#34;参数不是可选的&#34;。我还尝试使用AddressOf
传递回调函数,但我再次收到错误 - &#34;无效使用AddressOf运算符&#34;。
现在我的问题是 - 我做错了什么?将回调函数从Visual Basic传递给C#然后调用它的正确方法是什么。
感谢您的时间!
答案 0 :(得分:0)
COM无法看到任何包含泛型的内容,因此GetDataFromServer
Action<MyCustomType>
的COM AddressOf
不可见。您必须在非泛型类上定义一个方法,而不使用泛型类型参数,而不使用泛型参数或返回类型。
在COM中传递回调的常用方法是使用要调用的方法传递接口指针。避免使用IDispatch
方法,无论多么可行,一旦你希望回调在进程外工作,这是非常糟糕的做法。
IDispatch::Invoke
对象的一个常见技巧是使用DispId 0(DISPID_VALUE
)定义一个带有DispId 0({{3}})的默认方法的类,COM服务器可以通过VB_UserMemId
调用它。在某些语言中,例如JScript,可以通过这种技术调用对象。
要了解如何在VB6 / VBA中执行此操作,请搜索Sub Call()
Attribute Call.VB_UserMemId = 0
End Sub
。实际上,您必须以原始格式编辑类文件(在VBA中,必须将其导出)并添加属性,例如:
Call
在VBA中,您将删除该类并从已编辑的文件中导入。结果是Sub
方法现在显示为DispId 0.您可以随意调用它,但请记住同时编辑Attribute
名称和dynamic
。
在C#中,我认为实现此类调用的唯一方法是使用obj[0]
变量:
Type.InvokeMember
或通过IDispatch::Invoke
或类似的obj.GetType().InvokeMember("", BindingFlags.InvokeMethod, null, obj, null);
方法:
AddressOf
后者更可靠,你传递你想要的参数,而前者使用误导性语法并迫使你传递参数。
通常,如果你控制整个情况并且你不需要可调用的对象,那么只需要一个简单的方法。
关于DisplayOptionQuotes
错误,此运算符适用于模块过程和函数,因此您看到的错误可能是因为public static IList<ForumTopicReply> getTopicRepliesByTopicId(int forumId, int categoryId, int topicId, string orderBy)
{
var ctx = new dataContext();
IList<ForumTopicReply> forumTopicReplies = (from r in ctx.ForumTopicReplies
where r.ForumId == forumId && r.ForumCategoryId == categoryId && r.ForumTopicId == topicId
orderby r.DateCreated descending
select r).ToList();
return forumTopicReplies;
}
是一种方法。