Search code examples
c++dllcomvb6volume-shadow-service

C++ DLL which can inform a calling program about its progress


My boss wants me to write a DLL in C++ (MSVC++2010) which can perform a Volume Shadow Copy which he can call from VB6 (or at a later point other languages) and which can give status updates back while it is not finished. He calls it "events".

I have the feeling that I finally need to learn COM (I'd rather not ...) ... also, a callback function comes to my mind, but it's surely impossible to hand over function pointers from VB6 to C++?

Can someone outline what I have to learn and how this can be accomplished, with or without COM?

EDIT: to answer a question, the work flow is supposed to be:

  1. VB6 app determines which files to back up

  2. I am given a path and make a temporary volume shadow copy which includes this path and give back a mount point (or similar)

    • during this step, I regularly tell the VB6 app how far I am

  3. VB6 app makes backup of shadow copy and then deletes shadow copy.


Solution

  • You can pass a pointer to your "display progress" function from the VB app to the C++ DLL app using the AddressOf operator:

    Declare Function CallMyDll ...
    
    Sub DisplayStatus(ByVal SomeParameter As Long)
        ' ...
    End SUb
    
    Sub DoSomething()
        Call CallMyDll(AddressOf DisplayStatus)
    End Sub
    

    Some not so obvious gotchas:

    1. You have to declare your C++ function pointer using the __stdcall calling convention. (Thanks, Alexandre C!)

    2. In your VB callback function, explicitly mark your parameters as by-value using the keyword ByVal. Similarly, in your C++ function pointer, don't mark your parameters as by-reference.

    3. If you want to pass a string to the callback, or retrieve a string from it, you have to take into consideration that VB Strings are not equal to C char*s, C++ std::strings, or Microsoft's CStrings. VB Strings must be mapped to Microsoft's rather obscure BSTR data type.

    4. I forgot a very important thing: Your callback has to be inside a VB Module (i.e., it has to be a "mere function", not a class' or a form's method).