回调函数:从c# winform应用程序传递回调到引用的vc++ Exe

本文关键字:回调 引用 Exe vc++ 应用程序 函数 winform | 更新日期: 2023-09-27 17:55:02

异步回调函数

视角:我正在将几个VB6 ActiveX应用程序升级到c# .net,它们都使用回调函数相互通信,这些回调函数注册到参考的vc++ .net可执行文件中。

我无法在c#中复制以下VB6功能:VB6将包含方法的实例化类作为回调函数参数传递给vc++的能力,vc++随后将其注册为异步通信的回调函数。

升级进行得非常顺利,除了这一个问题:CallBack Functions…到现在我已经被它困了两个星期了。请帮帮我!!

我已经弄清楚如何传递回调函数作为委托,我已经设法与c# DynamicInvoke一起工作,但是我真的需要这个在vc++中工作。

错误信息我一直从 vc++ invoke语句中获得"Invalid Number of parameter "


下面我概述了VB6和vc++处理异步回调的功能。VB6 ActiveX组件每个都传递一个类,其中包含一个方法作为vc++可执行文件的回调函数,它将回调保存在一个数组中供以后使用。因为这是现有的代码,所以它按预期工作。

下面是VB6Class1实例化并用作回调:
请注意:Attribute Notify.VB_UserMemId = 0

VERSION 1.0 CLASS
BEGIN
 MultiUse = -1       
 Persistable = 0 
 DataBindingBehavior = 0 
 DataSourceBehavior  = 0 
 MTSTransactionMode  = 0 
END
Attribute VB_Name = "Class1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
 
Sub Notify(ByVal message As Integer, ByVal data As Variant)
Attribute Notify.VB_UserMemId = 0
  MsgBox Str$(message) + "  " + data, vbInformation, Form1.Text2
End Sub

以上代码已被简化以避免混淆。

下面是VB6代码,它实例化了vc++可执行文件(VCCallbackHandler),并将实例化的Class1作为回调参数传递给它

Dim VCCallbackHandler New VCCallbackHandler.VCCallbackHandler 
Dim c1 As New Class1
Private Sub Register_Click()
   Dim i as int
   i = VCCallbackHandler.Register(c1, "NameOfApplication")
End Sub

vc++代码注册回调(见下文),然后(异步)vc++可以利用回调,如果有其他事件提示(见下文'BroadCast')。在这种情况下,vc++ exe作为几个并发运行的应用程序的中央回调处理程序。每个应用程序都在vc++回调处理程序中注册了它们的回调函数,当一个应用程序通过调用另一个事件来提示vc++ callbackHandler时,所有的回调函数都被调用。通过这种方式,回调处理程序允许所有这些其他应用程序相互通信。

下面是相关的 vc++。. Net回调代码。

注册回调:

 #define MAXREG  20
 typedef struct tagRegElement {
    char    name[20];       // Name of registered application
    _Callback   *p_Callback;    // Callback wrapper class
 } REG_ELEMENT;
public:
     REG_ELEMENT Registry[MAXREG];

short CBreqDlgAutoProxy::Register(LPDISPATCH callback, LPCTSTR name) 
{
    for (int i = 0;i<MAXREG;i++){
        if(!(theApp.Registry[i].name[0]))
        {
            RegIndex = i;
            strcpy(theApp.Registry[i].name,name);
            theApp.Registry[i].p_Callback = new _Callback(callback);
            return i;
        }
    }
 
    return -1;
 }

调用回调:

 BOOL CBreqDlgAutoProxy::Broadcast(short message, const VARIANT FAR& data) 
 {
    for (int i = 0;i<MAXREG;i++){
        if(theApp.Registry[i].name[0] && (i != RegIndex)){
            if (!theApp.Registry[i].p_Callback->Notify(message,data,theApp.Registry[i].name))
                DeRegister(i);
        }
    }
    
    return TRUE;
 }
 BOOL _Callback::Notify(short message, VARIANT data, char* RegisteredName)
 {
    static BYTE parms[] = VTS_I2 VTS_VARIANT;
        
    InvokeHelper(0x0, DISPATCH_METHOD, VT_EMPTY, NULL, parms, message, &data);
     
    return TRUE;
 }

上述作品

有两个可能的解决方案:

    c#:如何让c#传递一个方法作为参数。我想出了如何使用委托来完成它,但是vc++想要一个方法而不是委托。
  1. vc++:如何让vc++处理委托而不是方法作为回调调用。

我没有成功使用以下任何c#代码片段:'

  • Marshal.GetFunctionPointerForDelegate
  • GCHandle
  • KeepAlive

我希望有人有这个问题,可以去…拍……很简单. .用这个……交叉手指。

回调函数:从c# winform应用程序传递回调到引用的vc++ Exe

我以前做过类似的事情,但我用它来传递变量。

c#:如何让c#传递一个方法作为参数。我想出了如何使用委托来做到这一点,但是vc++想要一个方法而不是委托。

我使用c++/CLI,因为c#代码(托管)不能直接与vc++代码(非托管)对话。

所以如果你能写一个CLI/c++包装器,那将会有帮助。

p。我想知道如何将委托传递给vc++。如果你能发布代码,那就太好了。