Hi All -
Have a little problem that I hope someone can help with.
I have a MT com .exe app that fires events (connection points) from a worker
thread which is a COM MTA. It has been working fine with a VB 6 client. I am
trying to port the client to VB.net but I am having problems. The event will
fire once, but the app will then freeze and I can not seem to determine
where the problem lies; I suspect the interface pointer may be changing via
CLR or maybe some typing issues (i.e variants, return code, etc). Note I am
using MTA not GIT - would GIT work better? Any help is greatly appriciated.
Here is some of the relavent code:
VB.net:
Imports System
Imports System.Runtime.InteropServices
Public Class Form1
Inherits System.Windows.Forms.Form
Public WithEvents Manager As New AVXYZ.MYGUI
'' code removed for brevity...
''event handler - fires once then hangs
Private Sub OnStatusChange(ByVal StatusCode As Integer, ByVal StatusMessage
As String) Handles Manager.OnStatusChange
Dim ItemText As String
''
PictureBox1.Visible = True
Button1.Enabled = True
Button2.Enabled = True
Button3.Enabled = True
Button4.Enabled = True
Button5.Enabled = True
ItemText = CStr(StatusCode) & " : " & StatusMessage
MsgBox(ItemText)
End Sub
C++ Com
// Interface pointer (code simplified)
STDMETHODIMP CMYGUI::Initialize()
{
// starts worker
m_pManager = (CMYManager*)CMYManager::Start();
if(!m_pManger) {
MessageBox(NULL, "\nError: Manager Failed to start", "Error!", 0);
return E_FAIL;
} else {
// save this to m_pMyGui
m_pManager->myRegisterForEvents(this);
}
return S_OK;
}
In simplifed Worker:
long StatusCode = 100;
CComBSTR StatusMessage = "Firing test Event";
while(m_ThreadState == RUNNING) {
Sleep(10000);
m_pMyGui->Fire_OnStatusChange(StatusCode, StatusMessage);
}
Connection Point "Fire"
#include "ATLCPImplMT.h"
template <class T>
class CProxy_IMYGUIEvents : public IConnectionPointImplMT<T,
&DIID__IMYGUIEvents, CComDynamicUnkArray>
{
public:
HRESULT Fire_OnStatusChange(long StatusCode, BSTR StatusMessage)
{
CComVariant varResult;
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[2];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections;
nConnectionIndex++)
{
CComPtr<IUnknown> sp;
sp.Attach (GetInterfaceAt(nConnectionIndex));
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
VariantClear(&varResult);
pvars[1] = StatusCode;
pvars[0] = StatusMessage;
DISPPARAMS disp = { pvars, NULL, 2, 0 };
pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD,
&disp, &varResult, NULL, NULL);
}
}
delete[] pvars;
return varResult.scode;
}
};
IDL (not complete)
dispinterface _IMYGUIEvents
{
properties:
methods:
[id(1), helpstring("method OnStatusChange")] HRESULT OnStatusChange(long
StatusCode, BSTR StatusMessage);
};
[
uuid(xxxxxREMOVED FOR POSTxxxxxxxxxxxxxxxxxx),
helpstring("MYGUI Class")
]
coclass MYGUI
{
[default] interface IMYGUI;
[default, source] dispinterface _IMYGUIEvents;
};
Willy Denoyette [MVP] - 23 Feb 2006 11:02 GMT
No, you don't have to use the GIT, the CLR aggregates the Free Threaded
Marshaler at the CCW side.
Just some questions though, what kind of COM object is this (free or both),
are you sure the worker thread is entering the MTA (CoInitialized
Multithreaded)?
The reason I'm asking is this: VB runs in a STA initialized thread, that
means that the call backs must be marshaled (MTA-STA), however when the
callback (the event source) is running in an STA, this thread must pump the
message queue in order to get the result from the previous call (fire).
In your code sample this isn't the case,
| while(m_ThreadState == RUNNING) {
|
| Sleep(10000);
instead, you are blocking the thread for 10 seconds after which you fire the
next event, this call (firing is the same as calling a method, right) will
be blocked until your thread has picked up the previous return value
(HRESULT) from the channel.
Note that an MTA thread does not have to pump (at least not here) messages,
as it pumps in the channel, So this is something you have to investigate.
Willy.
| Hi All -
| Have a little problem that I hope someone can help with.
[quoted text clipped - 189 lines]
|
| };