C ++ DLL,可以通知调用程序其进度

时间:2011-03-17 15:16:00

标签: c++ dll com vb6 volume-shadow-service

我的老板要我用C ++编写一个DLL(MSVC ++ 2010),它可以执行卷影复制,他可以从VB6(或稍后的其他语言)调用它,并且可以在其中提供状态更新。还没完呢。他称之为“事件”。

我觉得我终于需要学习COM(我宁愿不......)...而且,我想到了一个回调函数,但是从VB6到C ++的函数指针肯定是不可能的。 ?

有人可以概述我必须学习的内容以及如何在有或没有COM的情况下实现这一目标吗?

编辑: 回答一个问题,工作流程应该是:

  1. VB6应用确定要备份的文件

  2. 我获得了一个路径并制作了一个临时卷影副本,其中包含此路径并返回一个挂载点(或类似的)

    • 在此步骤中,我会定期告诉VB6应用程序

  3. VB6应用程序备份卷影副本,然后删除卷影副本。

6 个答案:

答案 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

一些不那么明显的陷阱:

  1. 您必须使用__stdcall calling convention声明C ++函数指针。 (谢谢,Alexandre C!)

  2. 在VB回调函数中explicitly mark your parameters as by-value使用关键字ByVal。同样,在C ++函数指针中,不要将参数标记为按引用。

  3. 如果要将字符串传递给回调或从中检索字符串,则必须考虑到VB String不等于C char* s, C ++ std::string s或Microsoft的CString。 VB String必须映射到Microsoft相当模糊的BSTR数据类型。

  4. 我忘记了一个非常重要的事情:你的回调必须在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的整数以表示进度

  • 这样VB应用程序可以并行启动多个操作。

执行复制的线程应该不时地更新“progress”变量。 DLL中用于停止复制的另一个函数也很有用。