回调函数:将回调从C#winform应用程序传递到引用的VC++;Exe 异步回调函数

回调函数:将回调从C#winform应用程序传递到引用的VC++;Exe 异步回调函数,c#,visual-c++,vb6-migration,asynccallback,dynamic-invoke,C#,Visual C++,Vb6 Migration,Asynccallback,Dynamic Invoke,透视图:我正在将几个VB6 ActiveX应用程序升级到C#.net,这些应用程序都使用回调函数相互通信,它们将回调函数注册到引用的VC++.net可执行文件中 我无法在C#中复制以下VB6功能: VB6将包含方法的实例化类作为回调函数参数传递给VC++的能力,然后VC++将其注册为异步通信的回调函数 除了这个问题外,升级进展非常顺利:回调函数 ... 我已经坚持了两个星期了。请帮帮我 我已经知道了如何以委托的形式传递回调函数,我已经成功地使用C#DynamicInvoke实现了这一点,但是我真

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

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

除了这个问题外,升级进展非常顺利:回调函数 ... 我已经坚持了两个星期了。请帮帮我

我已经知道了如何以委托的形式传递回调函数,我已经成功地使用C#DynamicInvoke实现了这一点,但是我真的需要它来在VC++中工作

我一直从VC++
invoke
语句中得到的错误消息是“参数数无效”


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

下面是正在实例化并用作回调的VB6
Class1
: 请注意:
Attribute Notify.VB\u 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
为了避免混淆,上面的代码已经简化

下面是实例化VC++可执行文件(
VCCallbackHandler
)的VB6代码,并将实例化的
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++可以在其他事件(见下文“广播”)提示下使用回调。在这种情况下,VC++exe充当几个同时运行的应用程序的中央回调处理程序。每个应用程序都已向VC++回调处理程序注册了回调,当一个应用程序通过调用另一个事件提示VC++回调处理程序时,将调用所有回调。通过这种方式,回调处理程序允许所有其他应用程序相互通信

下面是相关的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;
 }
#定义MAXREG 20
typedef结构tagRegElement{
char name[20];//已注册应用程序的名称
_Callback*p_Callback;//回调包装器类
}REG_元素;
公众:
注册表元素注册表[MAXREG];
短CBreqDlgAutoProxy::寄存器(LPDISPATCH回调,LPCTSTR名称)
{

对于(inti=0;i我以前做过类似的事情,但我用它来传递变量

C#:如何让C#将方法作为参数传递。我知道如何使用委托进行传递,但VC++想要的是方法而不是委托

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

因此,如果您可以编写CLI/C++包装器,这将有所帮助


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

声明一个方法的委托。公共委托void NotifyDG(int message,string msgData);静态void notify(int message,string msgData){System.Windows.Forms.MessageBox.Show(“test”);}然后调用传入委托NotifyDG d=newnotifydg(notify);i=VCCallbackHandler.Register(d,“NameOfApplication”)的vc++代码;然而,正如我前面所说的。。虽然注册步骤有效,但当我尝试使用invokeHelper方法时,它失败了。nnfghhhdhdgfsdgfsdgf…很抱歉,无法使此PrettierTanks Rip生效。我的解决方案有效吗?也许你可以创建一个名为add(int a,int b)的POC,并查看我的方法是否有效。@Rip,请转到本教程-