C++ DLL,可以通知调用程序其进度
我的老板希望我用 C++ (MSVC++2010) 编写一个 DLL,它可以执行卷影复制,他可以从 VB6(或稍后其他语言)调用它,并且可以在未完成时返回状态更新。他称之为“事件”。
我有一种感觉,我终于需要学习COM了(我宁愿不...)...而且,我想到了一个回调函数,但是函数指针从VB6移交给C++肯定是不可能的?
有人可以概述一下我必须学习什么以及如何在使用或不使用 COM 的情况下实现这一点吗?
编辑: 回答一个问题,工作流程应该是:
VB6 应用程序确定要备份哪些文件
我得到一个路径并创建一个临时卷影子复制其中包含此路径并返回安装点(或类似的)
- 在此步骤中,我会定期告诉 VB6 应用程序我还有多远
VB6 应用程序备份卷影副本,然后删除卷影副本。
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:
VB6 app determines which files to back up
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
VB6 app makes backup of shadow copy and then deletes shadow copy.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以使用
AddressOf
运算符将指向“显示进度”函数的指针从 VB 应用程序传递到 C++ DLL 应用程序:一些不太明显的陷阱:
您必须声明 C++ 函数指针使用
__stdcall
调用约定。 (谢谢,Alexandre C!)在您的 VB 回调函数中,将您的参数显式标记为按值< /a> 使用关键字
ByVal
。同样,在 C++ 函数指针中,不要将参数标记为引用。如果您想将字符串传递给回调,或从中检索字符串,则必须考虑到 VB
String
不等于 Cchar*、C++
std::string
或 Microsoft 的CString
。 VBString
必须映射到 Microsoft 相当晦涩的BSTR
数据类型。我忘记了一件非常重要的事情:您的回调必须位于 VB 模块内(即,它必须是“纯粹的函数”,而不是类或表单的方法)。< /p>
You can pass a pointer to your "display progress" function from the VB app to the C++ DLL app using the
AddressOf
operator:Some not so obvious gotchas:
You have to declare your C++ function pointer using the
__stdcall
calling convention. (Thanks, Alexandre C!)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.If you want to pass a string to the callback, or retrieve a string from it, you have to take into consideration that VB
String
s are not equal to Cchar*
s, C++std::string
s, or Microsoft'sCString
s. VBString
s must be mapped to Microsoft's rather obscureBSTR
data type.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).
您的老板可以使用 Declare 语句调用 DLL 导出的函数。这不能很好地扩展,但对于简单的 API 来说已经足够了。您的函数应使用 extern "C" 和 __declspec(dllexport) 声明符导出,使用 __stdcall 调用约定并仅使用简单的参数类型。
Your boss can call functions exported by a DLL with the Declare statement. That doesn't scale well but is fine for a simple API. Your function should be exported with the extern "C" and __declspec(dllexport) declarators, use the __stdcall calling convention and use only simple argument types.
什么时候必须提供这些状态更新?
设置 VSS 时?或者在备份数据之类的时候?
在后一种情况下,VSS仅返回一个路径,可以使用该路径
直接来自 VB。
但对于设置......这也可能有意义,因为它可能相当慢,
但我想你可以把它变成一个状态机 - 把所有的 VSS API 调用
进入一个大的 switch() 并创建一个函数来一一调用它们
更新状态变量。
更新:我的意思是这样的。
Init() 和 Step() 是由 dll 导出并从 VB 调用的函数。
或者,您可以生成一个线程来完成所有这些操作(仍在 dll 中)并返回
像 Step() 中的 Sleep(100) 一样,状态会更新。
When it has to provide these status updates?
While setting up VSS? Or while backing up the data and such?
In the latter case VSS just returns a path, which can be used
directly from VB.
But for setup... it might make sense too, because it can be fairly slow,
but I guess you can turn it into a state machine - put all the VSS API calls
into a big switch() and make a function which would call them one by one and
update the state var.
Update: I mean something like this.
Init() and Step() are your functions exported by your dll and called from VB.
Alternatively, you can spawn a thread to do all that (still in the dll) and return
status updates after like Sleep(100) in Step().
我会在没有 COM 的情况下完成这项工作。相反,我会让 VB 部分向 DLL 发送一个窗口句柄,然后 DLL 将向窗口发布一条消息,告知其进度。
您可以使用 COM,但这有点像用大锤打苍蝇。
I would do the job without COM. Instead, I'd have the VB part send a window handle to the DLL, and the DLL will post a message to the window telling its progress.
You could use COM, but that's kind of in the range of swatting a fly with a sledgehammer.
走unix-y路线。创建一个执行复制并将进度指示器输出到标准输出的程序。让 VB 应用程序解析此输出以获取完成百分比。
Take the unix-y route. Create a PROGRAM that performs the copy and outputs a progress indicator to std out. Make the VB app parse this output to grab the completion percentage.
我会这样做:
VB 应用程序调用 DLL 中的函数,要求启动卷影副本。您的 Dll 启动一个执行卷影复制的线程,并将 ID(线程 ID?)返回给 VB 应用程序
VB 应用程序定期调用 DLL 中的函数“Progress”,传递之前收到的操作 ID:进度函数返回一个 0-100 的整数来指示进度
执行复制的线程应该时不时地更新“进度”变量。
DLL 中另一个停止复制的函数也很有用。
I would do this:
the VB app calls the function in your DLL asking to start the shadow copy. Your Dll starts a thread that performs the shadow copy and returns an ID (a thread id?) back to the VB app
The VB app calls periodically a function "Progress" in your DLL passing the operation ID received before: the progress function returns an integer 0-100 to indicate the progress
The thread that performs the copy should update a "progress" variable every now and then.
Another function in the DLL that stops the copy would be useful too.