Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / February 2006

Tip: Looking for answers? Try searching our database.

Connection Point from MTA to vb.Net

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
S Wheeler - 22 Feb 2006 16:05 GMT
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]
|
| };

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.