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