2

我的老板希望我用 C++ (MSVC++2010) 编写一个 DLL,它可以执行卷影复制,他可以从 VB6(或稍后其他语言)调用它,并且可以在未完成时返回状态更新. 他称之为“事件”。

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

有人可以概述我必须学习的内容以及如何在有或没有 COM 的情况下完成这些吗?

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

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

  2. 我得到了一个路径并制作了一个包含此路径的临时卷影副本并返回了一个安装点(或类似的)

    • 在这一步中,我会定期告诉 VB6 应用程序我走了多远

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

4

6 回答 6

5

您可以使用运算符将​​指向“显示进度”函数的指针从 VB 应用程序传递到 C++ DLL 应用程序AddressOf

Declare Function CallMyDll ...

Sub DisplayStatus(ByVal SomeParameter As Long)
    ' ...
End SUb

Sub DoSomething()
    Call CallMyDll(AddressOf DisplayStatus)
End Sub

一些不那么明显的陷阱:

  1. __stdcall 您必须使用调用约定来声明您的 C++ 函数指针。(谢谢,亚历山大 C!)

  2. 在您的 VB 回调函数中,使用关键字将参数显式标记为按值ByVal。同样,在 C++ 函数指针中,不要将参数标记为引用。

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

  4. 我忘记了一件非常重要的事情:您的回调必须在 VB 模块中(即,它必须是“纯粹的函数”,而不是类或表单的方法)。

于 2011-03-17T17:20:06.147 回答
2

您的老板可以使用Declare语句调用由 DLL 导出的函数。这不能很好地扩展,但对于简单的 API 来说很好。您的函数应使用 extern "C" 和 __declspec(dllexport) 声明符导出,使用 __stdcall 调用约定并仅使用简单参数类型。

于 2011-03-17T16:27:15.513 回答
1

何时必须提供这些状态更新?
在设置 VSS 时?还是在备份数据等时?在后一种情况下,VSS 只返回一个路径,可以直接从 VB 中使用。
但是对于设置......它也可能有意义,因为它可能相当慢,但我想你可以将它变成一个状态机 - 将所有 VSS API 调用放入一个大 switch() 并创建一个函数来调用他们一一更新状态变量。

更新:我的意思是这样的。Init() 和 Step() 是由 dll 导出并从 VB 调用的函数。
或者,您可以生成一个线程来执行所有这些操作(仍在 dll 中)并在 Step() 中的 Sleep(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);
}
于 2011-03-17T15:37:05.837 回答
1

我会在没有 COM 的情况下完成这项工作。相反,我会让 VB 部分向 DLL 发送一个窗口句柄,然后 DLL 将向窗口发布一条消息,告知其进度。

您可以使用 COM,但这有点像用大锤击打苍蝇。

于 2011-03-17T16:02:17.223 回答
1

走 unix-y 路线。创建一个执行复制并将进度指示器输出到标准输出的程序。使 VB 应用程序解析此输出以获取完成百分比。

于 2011-03-17T16:19:55.060 回答
1

我会这样做:

  • VB 应用程序调用 DLL 中要求启动卷影副本的函数。您的 Dll 启动一个执行卷影复制的线程并将一个 ID(线程 ID?)返回给 VB 应用程序

  • VB 应用程序定期调用 DLL 中的函数“Progress”,传递之前收到的操作 ID:progress 函数返回一个整数 0-100 以指示进度

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

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

于 2011-03-17T21:09:17.157 回答