Adapting a DLL to VB.NET, using PINVOKE
-
I seem to be learning best the hard way, every time I try learning something the easy way I end up not knowing anything. This is why I love looking at other peoples code and learning their syntax. I have done a lot of work on my own serialport classes under VB.NET so most of this code is known to me. The unknown parts being delegating and event handling. I havent found a good tutorial on using delegates under VB.net nor on event handling, but I have both present here in this code sample, now if I could (given enough time) reverse engineer this, I would end up understanding both on a relatively known problem (serial port communication). VB.net is my language of choice, but I had done some minor work in C#, I have already compared C# and VB.net reflector outputs and this did help me solve SOME of the problems, just not all. I would be interested in reflector addon that turns an entire dll into source code, I have been searching under addons for it, but I havent been able to find it, is it third party (not listed on reflectors home page)? Yeah there some sort of a plugin for VS that handles PINVOKING, I also use it a lot. Turns out that using google shake and bake solutions makes me patchwork code together without knowing WHY it works, unfortunately due to time constraints on my projects, I do the majority of things this way. AFAIK most programmers do. It makes me feel unsecure about my knowledge and the behaviour of the code that isnt all mine. I love learning how the stuff actually works.
IMO the quickest way to learn a new technology is by reading a book about it. A tutorial is meant to take you from zero to first understanding; you will not be getting why things are done a particular way, and not another way, just by looking at existing code. I can't help you with articles on delegates and events if you insist on them using VB examples. :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
Prolific encyclopedia fixture proof-reader browser patron addict?
We all depend on the beast below.
-
Now thats a good tip, I was aware of the various types but I did not know how to easily fix problems like the above.
-
you are mixing signed and unsigned integers. It isn't very important which you choose, however being consistent is what matters. So either make BR an unsigned integer (use the U suffix again!), or modify the structure to a signed baudrate. The P/Invoke stuff will not mind you doing so. :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
Prolific encyclopedia fixture proof-reader browser patron addict?
We all depend on the beast below.
-
Hrizip wrote:
Dim key As New RegKey(&H80000002)
I don't know what
class RegKey
is, nor what constructor(s) it has. If it needs an unsigned integer parameter, once again apply a U suffix or switch to a signed integer definition. :)Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
Prolific encyclopedia fixture proof-reader browser patron addict?
We all depend on the beast below.
-
I am trying to dissasemble a .net dll via reflector, one that has been in use in our company for ages, as practice. My future task will be to produce similar dll-a that are com interoparabile and activex compliant. I am doing this in VB.net, and I have already been told that this is a big no-no, dlls of this sort are supposed to be made with C++ people say. I would guess that they are stating this because C++ uses pointers (which are heavily used in many DLLs when it comes to pointing to a pointer - i.e. memory location that holds particular relevant info). Be as it may, I wish to proceed building this dll in vb.net to see how far I can get before I am forced to switch to C++ or C#... I have already made a lot of fixes to the code, thus reducing the number of errors from over 120 to 30 which is, I would guess, a good start, but now I am facing several errors that are above my level of knowledge (I am a beginner after all) and I would like to get some information from people who are more experienced than me. * First problem I encountered is the following: (this is an excerpt of code dealing with events that happen on a SERIAL port).
Public Custom Event OnCTS As OnCTS
AddHandler(ByVal value As OnCTS)
Me.OnCTS = DirectCast(Delegate.Combine(DirectCast(Me.OnCTS, Delegate), DirectCast(value, Delegate)), OnCTS)
End AddHandler
RemoveHandler(ByVal value As OnCTS)
Me.OnCTS = DirectCast(Delegate.Remove(DirectCast(Me.OnCTS, Delegate), DirectCast(value, Delegate)), OnCTS)
End RemoveHandler
End EventThis is what the reflector did for me, unfortunately the first "DELEGATE" keyword after DirectCast has an error attached to it: "expression expected". I have tried using "raiseevent" instead but if I use that, another piece of code later will not work. Currently I have this:
Public Custom Event OnCTS As OnCTS
AddHandler(ByVal value As OnCTS)End AddHandler RaiseEvent() End RaiseEvent RemoveHandler() End RemoveHandler End Event
But I do not know the proper syntax for this nor where to begin. I have only recently started doing event driven code. * A similar error (DELEGATE keyword, "keyword does not name a type") happens in this line of code:
Me.parent.Invoke(DirectCast(New EventHandler(AddressOf callback.ToMainThread), Delegate))
* The third problem is in this line of code
Fixed a few things; 1) Delegate is a system.delegate method so there was a problem in namespaces, had to explicitly state what a "DELEGATE" is (a system.delegate in this case) 2) Unresolved at this time, mostly because I am clueless when it comes to delegates ;) This is the C# variant of one of the events/delegates:
public delegate void OnForceClose(int ErrorCode);
public event OnForceClose OnForceClose;
When expanded it reveals the following:
[MethodImpl(MethodImplOptions.Synchronized)]
public void add_OnForceClose(OnForceClose value)
{
this.OnForceClose = (OnForceClose) Delegate.Combine(this.OnForceClose, value);
}[MethodImpl(MethodImplOptions.Synchronized)]
public void remove_OnForceClose(OnForceClose value)
{
this.OnForceClose = (OnForceClose) Delegate.Remove(this.OnForceClose, value);
}VB.net variant looks like this:
Public Custom Event OnForceClose As OnForceClose
MethodImpl(MethodImplOptions.Synchronized) _
Public Sub add_OnForceClose(ByVal value As OnForceClose)
Me.OnForceClose = DirectCast(Delegate.Combine(Me.OnForceClose, value), OnForceClose)
End SubMethodImpl(MethodImplOptions.Synchronized) _
Public Sub remove_OnForceClose(ByVal value As OnForceClose)
Me.OnForceClose = DirectCast(Delegate.Remove(Me.OnForceClose, value), OnForceClose)
End SubI have no idea what this does, I can make an educated guess and say that this delegate is "announced" by using an older routine that does not use "add handler", "remove handler" and "raiseevent" instead it plugs into an older system.delegate method and therefore uses a different way of adding and removing a handler (see c# example). The VB example seems to show how to splice two delegates (or events) into one by the means of system.delegate.combine method, I have no idea why this is used in this example and what it should accomplish. I would need to find out what the difference is between the above mentioned examples and the addhandler/removehandler/raiseevent (which I am partly familiar with) and then try to recreate the whole thing. Any help/insight would be most welcome.
-
Fixed a few things; 1) Delegate is a system.delegate method so there was a problem in namespaces, had to explicitly state what a "DELEGATE" is (a system.delegate in this case) 2) Unresolved at this time, mostly because I am clueless when it comes to delegates ;) This is the C# variant of one of the events/delegates:
public delegate void OnForceClose(int ErrorCode);
public event OnForceClose OnForceClose;
When expanded it reveals the following:
[MethodImpl(MethodImplOptions.Synchronized)]
public void add_OnForceClose(OnForceClose value)
{
this.OnForceClose = (OnForceClose) Delegate.Combine(this.OnForceClose, value);
}[MethodImpl(MethodImplOptions.Synchronized)]
public void remove_OnForceClose(OnForceClose value)
{
this.OnForceClose = (OnForceClose) Delegate.Remove(this.OnForceClose, value);
}VB.net variant looks like this:
Public Custom Event OnForceClose As OnForceClose
MethodImpl(MethodImplOptions.Synchronized) _
Public Sub add_OnForceClose(ByVal value As OnForceClose)
Me.OnForceClose = DirectCast(Delegate.Combine(Me.OnForceClose, value), OnForceClose)
End SubMethodImpl(MethodImplOptions.Synchronized) _
Public Sub remove_OnForceClose(ByVal value As OnForceClose)
Me.OnForceClose = DirectCast(Delegate.Remove(Me.OnForceClose, value), OnForceClose)
End SubI have no idea what this does, I can make an educated guess and say that this delegate is "announced" by using an older routine that does not use "add handler", "remove handler" and "raiseevent" instead it plugs into an older system.delegate method and therefore uses a different way of adding and removing a handler (see c# example). The VB example seems to show how to splice two delegates (or events) into one by the means of system.delegate.combine method, I have no idea why this is used in this example and what it should accomplish. I would need to find out what the difference is between the above mentioned examples and the addhandler/removehandler/raiseevent (which I am partly familiar with) and then try to recreate the whole thing. Any help/insight would be most welcome.
Hi again, in normal situations, you don't need to go into the internals of events, i.e. I don't expect you would need Delegate.Combine at all. In normal circumstances, all the code you would need is what can be found in the MSDN example here[^]. There are three parts: 1. event declaration, with
event
keyword 2. event set-up, based onAddHandler
3. event processing, which looks like a regular method you have to provide. :)Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
If you want my opinion or comment, ask in a forum or on my profile page; I will not participate in frackin' Q&A
-
that would be "UI" not "UL", in .NET "long" variables take 64 bit, you don't need that, do you? :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
If you want my opinion or comment, ask in a forum or on my profile page; I will not participate in frackin' Q&A
-
that would be "UI" not "UL", in .NET "long" variables take 64 bit, you don't need that, do you? :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
If you want my opinion or comment, ask in a forum or on my profile page; I will not participate in frackin' Q&A
-
Hi again, in normal situations, you don't need to go into the internals of events, i.e. I don't expect you would need Delegate.Combine at all. In normal circumstances, all the code you would need is what can be found in the MSDN example here[^]. There are three parts: 1. event declaration, with
event
keyword 2. event set-up, based onAddHandler
3. event processing, which looks like a regular method you have to provide. :)Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
If you want my opinion or comment, ask in a forum or on my profile page; I will not participate in frackin' Q&A
I am looking into it right now, hopefully I will be able to rewrite the functionality of this part of code using normal VB.net syntax as shown on MSDN. That is the only remaining error by the way, I have fixed all the other errors except for this one concerning events and delegates.
-
I am trying to dissasemble a .net dll via reflector, one that has been in use in our company for ages, as practice. My future task will be to produce similar dll-a that are com interoparabile and activex compliant. I am doing this in VB.net, and I have already been told that this is a big no-no, dlls of this sort are supposed to be made with C++ people say. I would guess that they are stating this because C++ uses pointers (which are heavily used in many DLLs when it comes to pointing to a pointer - i.e. memory location that holds particular relevant info). Be as it may, I wish to proceed building this dll in vb.net to see how far I can get before I am forced to switch to C++ or C#... I have already made a lot of fixes to the code, thus reducing the number of errors from over 120 to 30 which is, I would guess, a good start, but now I am facing several errors that are above my level of knowledge (I am a beginner after all) and I would like to get some information from people who are more experienced than me. * First problem I encountered is the following: (this is an excerpt of code dealing with events that happen on a SERIAL port).
Public Custom Event OnCTS As OnCTS
AddHandler(ByVal value As OnCTS)
Me.OnCTS = DirectCast(Delegate.Combine(DirectCast(Me.OnCTS, Delegate), DirectCast(value, Delegate)), OnCTS)
End AddHandler
RemoveHandler(ByVal value As OnCTS)
Me.OnCTS = DirectCast(Delegate.Remove(DirectCast(Me.OnCTS, Delegate), DirectCast(value, Delegate)), OnCTS)
End RemoveHandler
End EventThis is what the reflector did for me, unfortunately the first "DELEGATE" keyword after DirectCast has an error attached to it: "expression expected". I have tried using "raiseevent" instead but if I use that, another piece of code later will not work. Currently I have this:
Public Custom Event OnCTS As OnCTS
AddHandler(ByVal value As OnCTS)End AddHandler RaiseEvent() End RaiseEvent RemoveHandler() End RemoveHandler End Event
But I do not know the proper syntax for this nor where to begin. I have only recently started doing event driven code. * A similar error (DELEGATE keyword, "keyword does not name a type") happens in this line of code:
Me.parent.Invoke(DirectCast(New EventHandler(AddressOf callback.ToMainThread), Delegate))
* The third problem is in this line of code
Dim numRef As Byte*
Fixed numRef = bufferI have this thing that puzzles me. :omg: I suppose that fixed means that garbage collector isnt allowed anywhere near the memory location to prevent accidental removal. That I can do in VB.net. :thumbsup: On the other hand I have no idea what Byte* is, seems to me its a pointer, what I do know from debugging is that it seems to retain only the first element in buffer (which is an array of 1023 I think, irrelevant at this point). Does the pointer point only to the first element? :confused: So if you store 1023 bytes in byte* it retains only the first byte? Please help ;) Added more info at 12:00 The next line of code is the following;
flag2 = Win32.ReadFile(Me.m_handle, numRef, 50, (numBytesRead), AddressOf overlapped)
numref in this case is taken from the line before and hence flag2 returns boolean true. Interesting thing is, in my patchwork code I use the following
Dim flag2 As Boolean = False
Dim numRef As Byte() = Nothing
numBytesRead = Nothing
numRef = buffer
flag2 = False
flag2 = Win32Serijski.ReadFile(Me.m_handle, numRef, 50, numBytesRead, overl)And in contrast to the original code, my flag2 ALWAYS returns TRUE, while in the original code it returns true only if theres NEW data in the buffer. :confused: