我的老板要我用C ++编写一个DLL(MSVC ++ 2010),它可以执行卷影复制,他可以从VB6(或稍后的其他语言)调用它,并且可以在其中提供状态更新。还没完呢。他称之为“事件”。
我觉得我终于需要学习COM(我宁愿不......)...而且,我想到了一个回调函数,但是从VB6到C ++的函数指针肯定是不可能的。 ?
有人可以概述我必须学习的内容以及如何在有或没有COM的情况下实现这一目标吗?
编辑: 回答一个问题,工作流程应该是:
VB6应用确定要备份的文件
我获得了一个路径并制作了一个临时卷影副本,其中包含此路径并返回一个挂载点(或类似的)
VB6应用程序备份卷影副本,然后删除卷影副本。
答案 0 :(得分:5)
您可以使用AddressOf
运算符将指针从VB应用程序传递到“显示进度”功能到C ++ DLL应用程序:
Declare Function CallMyDll ...
Sub DisplayStatus(ByVal SomeParameter As Long)
' ...
End SUb
Sub DoSomething()
Call CallMyDll(AddressOf DisplayStatus)
End Sub
一些不那么明显的陷阱:
您必须使用__stdcall
calling convention声明C ++函数指针。 (谢谢,Alexandre C!)
在VB回调函数中explicitly mark your parameters as by-value使用关键字ByVal
。同样,在C ++函数指针中,不要将参数标记为按引用。
如果要将字符串传递给回调或从中检索字符串,则必须考虑到VB String
不等于C char*
s, C ++ std::string
s或Microsoft的CString
。 VB String
必须映射到Microsoft相当模糊的BSTR
数据类型。
我忘记了一个非常重要的事情:你的回调必须在VB模块中(即,它必须是“纯粹的功能”,而不是类或表单的方法)。强>
答案 1 :(得分:2)
您的老板可以使用 Declare 语句调用DLL导出的函数。这不是很好的扩展,但对于简单的API来说很好。您的函数应该使用extern“C”和__declspec(dllexport)声明符导出,使用__stdcall调用约定并仅使用简单的参数类型。
答案 2 :(得分:1)
什么时候必须提供这些状态更新? 在设置VSS的同时?或者在备份数据等时? 在后一种情况下,VSS只返回一个可以使用的路径 直接来自VB 但是对于设置......它也可能有意义,因为它可能相当慢, 但我想你可以把它变成状态机 - 把所有的VSS API调用 进入一个大的switch()并创建一个可以逐个调用它们的函数 更新状态变量
更新:我的意思是这样的。 Init()和Step()是你的dll导出的函数,从VB调用 或者,您可以生成一个线程来执行所有操作(仍然在dll中)并返回 状态更新,如步骤()中的睡眠(100)。
int s; // state
int Init( void ) { s=0; }
int Step( void ) {
switch( s ) {
default: break;
case 0:
CoInitialize(0); break;
case 1:
r = CreateVssBackupComponents(&vssc);
if( FAILED(r) ) s=-1;
if( vssc==0 ) s=-2;
break;
case 2:
r = vssc->InitializeForBackup();
if( FAILED(r) ) s=-3;
break;
case 3:
r = vssc->SetBackupState( FALSE, FALSE, VSS_BT_COPY, FALSE );
if( FAILED(r) ) s=-4;
break;
[...]
}
s += (s>=0);
}
答案 3 :(得分:1)
我会在没有COM的情况下完成这项工作。相反,我让VB部分向DLL发送一个窗口句柄,DLL将向窗口发送一条消息告诉它进展。
你可以使用COM,但这种方法在使用大锤拍打苍蝇的范围内。
答案 4 :(得分:1)
采用unix-y路线。创建一个执行复制的程序,并输出一个进度指示器到标准输出。让VB应用程序解析此输出以获取完成百分比。
答案 5 :(得分:1)
我会这样做:
VB应用程序调用DLL中的函数,要求启动卷影副本。你的Dll启动一个执行卷影副本的线程并将一个ID(一个线程ID?)返回给VB应用程序
VB应用程序定期调用DLL中的函数“Progress”,传递之前收到的操作ID:progress函数返回0-100的整数以表示进度
执行复制的线程应该不时地更新“progress”变量。 DLL中用于停止复制的另一个函数也很有用。