Author |
Topic |
|
MLong
19 Posts |
Posted - 17 Jul 2003 : 17:08:15
|
I'll be posting this elsewhere as well but it seemed appropriate here since it involves .NET and targeted for BitsyX. If not then sorry, just kill it.
I have an interesting problem. I have created a DLL in eVC4 with numerous classes. 4 functions are currently being exported. Only the function internals actually deal with the classes. I am successfully calling/using these functions from a VB.NET (SDA) program by directly declaring the function names just like I (old-style) would any w32 lib functions. So far this works pretty good on the BitsyX with CE.NET 4.2x
However, now I'm trying to figure out exactly how to handle an event raised in the DLL inside the VB.NET program. The DLL events are contained within class objects. Both interface and implementation are in the same source file as the non-related functions that are being exported.
To any eVC veterans: Do I need to specially export the classes or their methods in some way for them to even be accessible from a program that is trying to catch the events as described above? Any example?
To any VB.NET vets: I'm assuming at the moment I'll need to do numerous things with reflection, gettype and a host of other functions to be able to handle the desired events that reside in the DLL and that are also actually fired within the DLL. I simply need the VB.NET app internally notified when these events fire in the DLL. Any example? |
|
ctacke
877 Posts |
Posted - 17 Jul 2003 : 17:14:14
|
When you say "events" do you mean system events (i.e. CreateEvent, SetEvent, etc) or COM connection points? |
|
|
MLong
19 Posts |
Posted - 17 Jul 2003 : 17:29:10
|
quote: [i]Originally posted by ctacke[/i] [br]When you say "events" do you mean system events (i.e. CreateEvent, SetEvent, etc) or COM connection points?
Example from the DLL:
STDMETHODIMP CTestClass::FireThisEvent (QWORD qFired) { // Fired by internal object. MessageBox( NULL, L"Event FIRED!", L"EVENT", MB_OK ); return NOERROR; }
That method if part of the class. The class itself is created and the event is registered with other objects that cause it to fire. Currently, internally, everything is working in the DLL because when the appropriate trigger occurs the event is fired and the messagebox shows on the device. The function is called from VB.NET that ultimately causes it to fire in the DLL, via other objects that are instantiated as a result of calling the function. The basic problems is simply being able to link into the event (method) above inside the VB app so it, too, knows when it fired and can act on it.
I guess technically it's just a method of a class and not really an event, though it is being treated as such because it's address is registered as the event handler by/for a couple of objects. |
|
|
ctacke
877 Posts |
Posted - 17 Jul 2003 : 17:33:55
|
Ah, so it's really neither. The problem here is that you cannot pass a delegate across the P/Invoke boundary, which makes callbacks as well as this kind of implementation quite difficult.
Offhand my advice would be to have the C++ class create and raise a named system event. In your VB.NET app create an event class that runs a separate worker thread that does a WaitForSingleObject on that same named event(s) and then uses a delegate to notify you app of events. This will rpovide your VB.NET app developers a user-friendly event-driven interface to the C++ class. |
|
|
MLong
19 Posts |
Posted - 17 Jul 2003 : 17:42:10
|
That sounds pretty good. My hunch was the current implementation wasn't suitable, at all, for what I wanted outside the DLL, however it was an excellent solution prior to wanting the event externally because it was all self contained and activated.
I'll try round-2 in the morning and see if I can implement it as you describe. I already know how i'm going to do the VB.NET side of it. The tricky part (for me) will be the eVC side since I'm still such a newb at it.
|
|
|
MLong
19 Posts |
Posted - 18 Jul 2003 : 11:46:32
|
Having serious problems trying to locate a mechanism in .NET to actually wait on a named event. I seem to ultimately be going in circles encountering Mutex, AutoResetEvent, ManualResetEvent, WaitHndle etc etc. Nothing so far can actually take an argument for a named event. Should I just try and do this brute force using Win32 in the VB app or do you have direct experience with this particular problem and a 'managed' workaround? |
|
|
ctacke
877 Posts |
Posted - 18 Jul 2003 : 11:48:27
|
The "manageged" woraround is to P/Invoke CreateEvent and WaitForSingleObject. I'll post code in a separate topic shortly.
|
|
|
MLong
19 Posts |
Posted - 18 Jul 2003 : 11:50:32
|
quote: [i]Originally posted by ctacke[/i] [br]The "manageged" woraround is to P/Invoke CreateEvent and WaitForSingleObject. I'll post code in a separate topic shortly.
Yeah that's what it looks like it's boiling down too, and I why I mentioned it. The closest thing I've found so far is TypeDescriptor.CreateEvent but I'm not sure this is going to lead me toward a 'managed' answer either since I need to wait on the event created elsewhere, not create it here. |
|
|
ctacke
877 Posts |
Posted - 18 Jul 2003 : 11:55:03
|
Take a look at Topic 1033 |
|
|
MLong
19 Posts |
Posted - 18 Jul 2003 : 12:10:27
|
quote: [i]Originally posted by ctacke[/i] [br]Take a look at Topic 1033
Very close to a post from dotnet247 where the guy embedded all of it inside a C# class. That's excellent, simple code. For my purposes though, as far as I can tell, the only thing that applies to my VB.NET-side app is the last function:
public static int WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds) { return CEWaitForSingleObject(hHandle, dwMilliseconds); }
So I'll have to 'get' a handle to the named event I'm after in the first place within VB then call this function from a worker thread passing it the handle and some equiv INFINITE param. I'll see if my W32 book describes the process of getting a proper handle to a named event then see if I can port it to VB. The code you posted looks like it 'should' probably work directly in the DLL side since you're using the CE kernel32 lib equiv. Thanks.
Edited:
Looks like OpenEvent is the missing ingredient here for the VB side. |
Edited by - MLong on 18 Jul 2003 12:12:56 |
|
|
ctacke
877 Posts |
Posted - 18 Jul 2003 : 12:18:56
|
Use the CreateEvent call in the code at Topic 1033 to get the handle. Just use the exact same event name as what is used by your class. |
|
|
MLong
19 Posts |
Posted - 18 Jul 2003 : 12:22:46
|
quote: [i]Originally posted by ctacke[/i] [br]Use the CreateEvent call in the code at Topic 1033 to get the handle. Just use the exact same event name as what is used by your class.
Ahh I see here that CreateEvent will actually open the event if it already exists and simply throw a special error code but return a valid handle. Thought it might be easier to detect if the call succeeded using OpenEvent because it will return NULL if it fails on the call to get the existing event. So one way means detecting a NULL return for failure, and the other means deciphering a return code to see if it matches ERROR_ALREADY_EXISTS. Is there some drawback to using OpenEvent I'm not aware of? |
|
|
MLong
19 Posts |
Posted - 24 Jul 2003 : 11:13:47
|
After opening a case with Microsoft we finally got Studio 2003 talking to the device again.
I was able to finally attempt experiment round-2 using the event logic discussed here. It works great. Thanks man. Named Events are gonna save me some *serious* headaches. : ) |
|
|
|
Topic |
|