C++;DLL,它可以通知调用程序其进度 我的老板要我在C++(MSVC++ 2010)中编写一个DLL,它可以执行卷影复制,他可以从VB6调用(或者在以后的其他语言中),并且可以在没有完成的状态下返回状态更新。他称之为“事件”

C++;DLL,它可以通知调用程序其进度 我的老板要我在C++(MSVC++ 2010)中编写一个DLL,它可以执行卷影复制,他可以从VB6调用(或者在以后的其他语言中),并且可以在没有完成的状态下返回状态更新。他称之为“事件”,c++,dll,com,vb6,volume-shadow-service,C++,Dll,Com,Vb6,Volume Shadow Service,我有一种感觉,我终于需要学习COM了(我宁愿不要…)。。。同样,回调函数也出现在我的脑海中,但是把函数指针从VB6切换到C++ +/P>是不可能的。 有没有人能概述一下我必须学习什么,以及如何在有或没有COM的情况下完成这项工作 编辑: 要回答一个问题,工作流程应该是: VB6应用程序确定要备份的文件 我得到一个路径,并创建一个临时卷影副本,其中包括该路径并返回一个装载点(或类似) 在这一步中,我会定期告诉VB6应用程序我有多远 VB6应用程序备份卷影副本,然后删除卷影副本 何时必须提供这些

我有一种感觉,我终于需要学习COM了(我宁愿不要…)。。。同样,回调函数也出现在我的脑海中,但是把函数指针从VB6切换到C++ +/P>是不可能的。 有没有人能概述一下我必须学习什么,以及如何在有或没有COM的情况下完成这项工作

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

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

  • 我得到一个路径,并创建一个临时卷影副本,其中包括该路径并返回一个装载点(或类似)

    • 在这一步中,我会定期告诉VB6应用程序我有多远
  • VB6应用程序备份卷影副本,然后删除卷影副本


  • 何时必须提供这些状态更新?
    在设置VSS时?或者在备份数据等时? 在后一种情况下,VSS只返回一条路径,可以使用该路径 直接来自VB。
    但是对于设置。。。这可能也有道理,因为它可能相当慢, 但是我想你可以把它变成一个状态机——把所有的VSS API调用都放进去 将其转换为一个大开关()并生成一个函数,该函数将逐个调用它们 更新状态变量

    更新:我的意思是这样的。 Init()和Step()是dll导出并从VB调用的函数。
    或者,您可以生成一个线程来执行所有这些操作(仍在dll中)并返回 状态在步骤()中类似睡眠(100)后更新


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


    您可以使用COM,但这在某种程度上可以用大锤击打苍蝇。

    采用unix-y路线。创建执行复制并将进度指示器输出到std out的程序。让VB应用程序分析此输出以获取完成百分比。

    您的老板可以使用Declare语句调用DLL导出的函数。这不能很好地扩展,但对于简单的API来说很好。您的函数应该用Extn“C”和“.O-DESPECUR”(DLLISTH)声明符导出,使用“Y-YSTDCALL调用约定”,只使用简单的参数类型。

    < P>您可以通过使用“<代码>地址> <代码> >运算符:

    ,将指针从“VB应用程序”传递到C++ DLL应用程序。
    Declare Function CallMyDll ...
    
    Sub DisplayStatus(ByVal SomeParameter As Long)
        ' ...
    End SUb
    
    Sub DoSomething()
        Call CallMyDll(AddressOf DisplayStatus)
    End Sub
    
    一些不太明显的问题:

    >p>您必须使用SysSTDLea>代码>声明C++函数指针。(谢谢,Alexandre C!)

  • 在VB回调函数中,使用关键字
    ByVal
    。同样,在C++函数指针中,不要将参数标记为引用。

  • 如果您想将字符串传递给回调,或者从中检索字符串,则必须考虑到VB<代码>字符串 S不等于C<代码> CHAR*<代码> >,C++ >代码> STD::String < /Calp> S,或者微软的<代码> cString < /Cord>。VB
    String
    s必须映射到Microsoft相当模糊的
    BSTR
    数据类型

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

  • 我会这样做:

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

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

    • 这样,VB应用程序可以并行启动多个操作
    执行复制的线程应该不时更新一个“progress”变量。
    DLL中的另一个停止复制的函数也会很有用。

    你的意思是,VB6有一个线程,它定期检查变量是否已更改,我是通过引用给出的?这也是我向他建议的解决方案之一!特别感谢您提供了详细的过程,显然您以前使用过卷影副本!我已经看过了Windows SDK示例(VSHADOW.EXE 3.0),这对于初学者来说是非常困难的,因为它也在VBA中工作。注意,约定通常是
    stdcall
    (在VBA中),因此您必须在C代码中明确指定它。BSTR类型可以通过
    CComBstr
    std::wstring
    和一些您一生中编写过的神奇代码来处理。谢谢!实际上,检索字符串不是问题:BSTR还指向以零结尾的C字符串。另一种方法不起作用,因为
    BSTR
    的长度包含在
    BSTR-1
    ,afaik。您对
    \uu stdcall
    @Felix的操作是正确的:相反的操作是通过
    SysAllocString
    完成的。“如果你让VB释放字符串,就没有什么困难了。”亚历山大C:我喜欢C++,我喜欢OOP,我喜欢模板,但是处理VB使我陷入黑客模式。是的,在我的工作中,我们也需要用VB做“功能编程”。这太糟糕了。谢谢,这是我向他建议的解决方案之一。这与@Shelwien的回答(在他澄清之前)后我的想法非常相似。有一种可能性,这将是我选择的方式。这取决于是否需要同时启动多个备份,但我对此表示怀疑。不过,这是一个非常好和干净的选择,我一定会考虑。
    Declare Function CallMyDll ...
    
    Sub DisplayStatus(ByVal SomeParameter As Long)
        ' ...
    End SUb
    
    Sub DoSomething()
        Call CallMyDll(AddressOf DisplayStatus)
    End Sub