【发布时间】:2014-02-12 09:27:31
【问题描述】:
以下设置:
我有一个 .Net Dll,它有一个名为 LicenceVerifier 的异步方法 当方法完成时会触发一个事件。
public class LicenceVerifier
{
private readonly ILicence _licence;
private readonly int _programkey;
public delegate void LicencedCheckedEventHandler(object sender, LicenceVerifierResultArgs args);
public event LicencedCheckedEventHandler LicencedChecked;
public LicenceVerifier(int programKey)
{
_programkey = programKey;
_licence = GetLicensing();
}
public void IsValidLicenceAsync()
{
new Task(() =>
{
LicenceVerifierResult valid = LicenceVerifierResult.NotAvailable;
if (_licence != null)
valid = _licence.IsValid(_programkey);
LicencedChecked(this, new LicenceVerifierResultArgs(valid));
}).Start();
}
在 C++ 方面看起来是这样的:
void __stdcall CheckLicenseAsyncVb(int iPrgKey, int cbAddress)
{
LicenceVerifierCallback^ callback = gcnew LicenceVerifierCallback();
callback->lCallbackAddress = cbAddress;
callback->callbackType = VB;
//.Net object
LicenceVerifier^ licenceVerifier = gcnew LicenceVerifier(iPrgKey);
licenceVerifier->LicencedChecked += gcnew LicenceVerifier::LicencedCheckedEventHandler(callback, &LicenceVerifierCallback::handler);
licenceVerifier->IsValidLicenceAsync();
}
C++ 端的处理程序:
public ref class LicenceVerifierCallback
{
public:
CallbackType callbackType;
long lCallbackAddress;
void(*callbackFunction)(int);
void handler(System::Object^ sender, LicenceVerifierResultArgs^ e)
{
if(callbackType == VB)
ExecuteCallbackVb(convertResult(e->Result));
if(callbackType == C)
ExecuteCallbackC(callbackFunction, convertResult(e->Result));
};
int convertResult(LicenceVerifierResult verifierResult)
{
if(verifierResult == LicenceVerifierResult::Available)
return 0;
return 1;
}
void ExecuteCallbackVb(int result)
{
typedef void ( *FUNCPTR) (int iResult);
FUNCPTR callBackFunction;
callBackFunction = (FUNCPTR)lCallbackAddress;
callBackFunction(result);
};
vb6:
Private Sub LicenceCheck_Click()
Call CheckLicenseAsyncVb(20110, AddressOf ResultCallback)
End Sub
Public Declare Sub CheckLicenseAsyncVb Lib "LicensingIntfd.dll" Alias "_CheckLicenseAsyncVb@8" (ByVal prgKey As Long, ByVal address As Long)
Public Sub ResultCallback(ByVal result As Long) '
'MsgBox "I'll be never a friend of vb6: " & result
End Sub
我现在遇到了问题,回调将在工作线程而不是 UI 线程中运行,这意味着显示消息框的 vb6 调用将失败。 我可以简单地在回调方法中写入一个变量,然后在 UI 线程中轮询变量以进行更改。不过不太喜欢这个主意。 任何人都有一个更清洁的解决方案的想法,可能让 c++ 端在 UI 线程中执行回调(如何?)?
非常感谢任何帮助。
【问题讨论】:
-
中间的C++的目的是什么?您可以在 C# 中公开 COM 对象,以便 VB6 轻松使用。
-
因为我们实际上想尽量减少 COM 组件的使用。 .Net dll 周围的 c++ 包装器是我们能够在 c++ 和 vb6 程序中使用 .net 代码的常用方法。
-
如果您不打算在 C++ 中使用 COM,那么您需要一个隐藏窗口(静态)来发布消息,以便能够在 UI 线程上调用回调。
-
这听起来像是一个计划,谢谢。如果您不介意,有机会举一个简短的例子吗?
标签: c# c++ asynchronous vb6 callback