将 VB 函数回调作为参数传递给 .NET
Posted
技术标签:
【中文标题】将 VB 函数回调作为参数传递给 .NET【英文标题】:Pass VB Function callback as parameter to .NET 【发布时间】:2020-10-02 01:52:18 【问题描述】:Visual Basic 程序的一部分正在移至 .NET dll。
参数调用成功,一切正常。
如何在长时间运行的异步任务后传递 VB6 的回调函数以供 .NET 调用?
在 .NET 中
Public Delegate Function VBCallBackFunc() As Integer
Public Function DoSomething(a As String, b As String, c As String, _
parent As IntPtr, Optional ByVal CallbackAddr As VBCallBackFunc = Nothing) As Boolean Implements _DotNetLib.DoSomething
VB6
result = DotNetLib.DoSomething(strA, strB, strC, Me.hwnd, AddressOf DotNetCallback)
Public Function DotNetCallback() As Long
MsgBox ("Callback")
End Function
在VB的对象浏览器中:
Function DoSomething(strA As String, strB As String, strC As String,
parent As Long, [CallbackAddr As VBCallBackFunc]) As Boolean
Member of DotNetLib
但它说“AddressOf 运算符的使用无效”???
【问题讨论】:
DotNetCallback
在类模块中吗?
我尝试移动到类模块,现在是类型不匹配错误:/
它必须在一个普通的模块中。您引用的错误是在类模块中。
VB6 没有类型化的回调,它们应该是Long
。就 VB6 而言,VBCallBackFunc
是什么?
您应该改用 .NET COM 事件。它比原始回调更安全:docs.microsoft.com/en-us/previous-versions/dotnet/…
【参考方案1】:
使用Events相关的cmets是一个不错的选择,但是我更倾向于使用接口,所以这里有一个解决方案。
(手写代码,需要进行语法检查,名称可以清理,仅用于说明目的)
在 .NET 中:
为您的回调创建一个 COM 公开接口:
Public Interface IVBCallBack
Public Function VBCallBackFunc() As Integer
End Interface
改变你的 DoSomething 是这样的:
Public Function DoSomething(a As String, b As String, c As String, parent As IntPtr, ByVal CallbackAddr As IVBCallBack) As Boolean
在 VB6 中:
result = DotNetLib.DoSomething(strA, strB, strC, Me.hwnd, Me)
(你需要你的类、控件或表单到Implements IVBCallBack
)
Public Function IVBCallBack_VBCallBackFunc() As Long
MsgBox ("Callback")
End Function
确保在 .NET 端有一个方法来清理和释放所有引用,因为 .NET 持有对 VB6 对象的引用。
还有一点需要注意。不要在主 UI 线程以外的任何线程上回调 VB6!
【讨论】:
加一个 - AFAICR 在 COM/.Net 互操作中使用事件有点不稳定,所以我会选择这个选项 问题是“对于 .NET 在长时间运行的异步任务后调用”。事件应该保护开发人员免受线程或悬空交叉引用问题(提供 VB 代码泵 windows 消息) 可以在其他线程上调用事件,但可以肯定的是,正如我打开的那样,事件是一个不错的选择。过去我遇到过一些问题,我不记得具体的问题(VB6 现在已经过时了),所以我最终采用了接口方法并且从未回头。 有趣的是,我发现这篇文章 (***.com/questions/18224220/…) 表明我的警告可能为时过早,COM 互操作的魔力会处理线程。 YMMV 这很好用。在 VB6 实现 DotNetLib.IVBCallBack 后,现在在主线程中使用 Invoke 从 .NET 成功调用函数。做得很好,非常感谢!以上是关于将 VB 函数回调作为参数传递给 .NET的主要内容,如果未能解决你的问题,请参考以下文章