|
| AddressOf, .NET, and VB6.0 interoperability |
|
|
|
|
| Messages |
|
Related Types |
This message was discovered on microsoft.public.dotnet.languages.vb.
Responses highlighted in red are from those people who are likely to be able to contribute good, authoratitive information to this discussion. They include Microsoft employees, MVP's and others who IMHO contribute well to these kinds of discussions.
| BoloBaby |
OK, here's the problem...
I have a digital input/output card that exposes IRQs (digital input change-of-state) through a DLL function.
In VB6.0, I can use this ability through code that looks like this:
[Class1]
Public sub test() DIO_INT1_EventMessage 0, 0, 0, 0, AddressOf BE_ReadPort end sub
[standard module]
Declare Function DIO_INT1_EventMessage Lib "Pci-Dask.dll" (ByVal CardNumber As Integer, ByVal Int1Mode As Integer, ByVal windowHandle As Long, ByVal message As Long, ByVal callbackAddr As Long) As Integer
Public sub BE_ReadPort() 'do some stuff end sub
Take note that the sub that handles the event HAS to be in the standard module and NOT in a class module. This is just a limitation of VB6.0. This means that I can't raise any events in that sub... which is what I *really* need to do.
Anyway, the inability to raise events led me to try and set up a PInvoke wrapper in .NET. The problem is, the VB6.0 DLL for the digital I/O card accepts only "ByVal callbackAddr As Long" as the address for the callback function. In .NET, the AddressOf operator returns a System.Delegate type.
How can I make this code point to my delegate function in .NET? Or, alternatively, how can I use VB6.0 to raise the event? I already tried using a global object to raise the events. Doesn't seem to work...
Thanks.
|
|
|
| |
|
| |
| |
| Tom Shelton |
"BoloBaby" <Click here to reveal e-mail address> wrote in message news:Click here to reveal e-mail address... [Original message clipped]
Declare Function DIO_INT1_EventMessage Lib "Pci-Dask.dll" _ (ByVal CardNumber As Short, _ ByVal Init1Mode As Short, _ ByVal windowHandle As IntPtr, _ ByVal message As Integer, _ ByVal callbackAddr As MethodInvoker) As Short
Private mi As MethodInvoker = New MethodInvoker(BE_ReadPort)
Private Sub CallIt() DIO_INT1_EventMessage(..., ..., ..., Me.Handle, ..., mi) End Sub
Private sub BE_ReadPort() 'do some stuff end sub
Something like the above should get you up and running :)
-- Tom Shelton [MVP]
|
|
|
| |
|
| |
|
| |
| Konrad L. M. Rudolph |
Two answers:
BoloBaby wrote: [Original message clipped]
why don't you just invoke the class and let it handle the event? Just declare an object of the class on module scope. In the class, before calling the API, you set this object instance to "Me". then you can call a public procedure of this class from the callback function. Now, back in the class this certain public procedure uses RaiseEvent to raise an event. It's as simple as this.
[Original message clipped]
No problem at all, just declare the API accordingly, use the delegate type. The framework will take care of the needed conversion.
Example:
\\ Public Delegate Function FontEnumProc( _ ByVal NLF As LOGFONT, _ ByVal NTM As TEXTMETRIC, _ ByVal FontType As Int32, _ ByVal LParam As Int32 _ ) As Int32
Public Declare Function EnumFontFamilies Lib "gdi32" Alias "EnumFontFamiliesA" ( _ ByVal hDC As Int32, _ ByVal lpszFamily As String, _ ByVal lpEnumFontFamProc As FontEnumProc, _ ByVal lParam As Int32 _ ) As Long ///
should work just as well with your API.
-- Konrad - http://madrat.net/
|
|
|
| |
|
|
| |
| |
| Herfried K. Wagner [MVP] (VIP) |
* "Konrad L. M. Rudolph" <Click here to reveal e-mail address> scripsit: [Original message clipped]
ACK, but don't forget to store a reference to the delegate you pass to the API function in order to prevent the GC from removing it.
-- Herfried K. Wagner [MVP] <URL:http://dotnet.mvps.org/>
|
|
|
| |
|
|
| |
|
|
|
|
|
|
|
|
|
BootFX
Reliable and powerful .NET application framework. |
|
|
|
|
|
|