VB6 has the interesting capacity to compile to either native code or pseudo-code.
Native code is actual Intel machine code. Pseudo-Code is much like the .NET “Intermediate Language” or IL, although, I suspect, a little less refined<G>
Most VB6 programmers I’ve known tend to compile to Native code although pseudo-code can be quite handy in some circumstances. First, it compiles much faster. Second, the generated EXE’s or DLL’s are typically much smaller than Native code EXE’s or DLL’s.
But what if you want, or need, to tell the difference at run time?
You could write up a conditionally compiled constant, but then you have to remember to switch the condition when appropriate. Still, that’s probably the ideal way to go.
But, that’s not really a runtime solution, now, is it.
I happened upon the solution ages ago when I was researching an article I wrote for VBPJ about implementing TRY CATCH exceptions in VB6.
Essentially, you grab the first byte pointed to by a function pointer and check it. If it’s an &HA1, you’re in the IDE running pseudo-code.
If it’s &HBA, you’re running as compiled pseudo-code.
Anything else means you’re running compiled native code.
As far as I can tell, this technique works regardless of optimization settings, etc.
Yeah, it’s probably a little overkill, but that’s what hacking is all about. Plus, knowing whether you’re in the IDE without scrambling the state of the ERR variable is quite handy in some circumstances. I created a separate function for that purpose.
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
Private Function pGetAddr(addr As Long) As Long
'---- utility function for IsNative and IsIDE
pGetAddr = addr
End Function
Public Function IsNative() As Boolean
'---- determine whether we're running
' a Native code EXE, or a PsuedoCode exe
' Also can determine whether we're in
' IDE or not
'
' Now this is HardCode!
'
Static Inited As Boolean
Static bIsNative As Boolean
Dim b As Byte
If Not Inited Then
CopyMemory b, ByVal pGetAddr(AddressOf pGetAddr), 1
Select Case b
Case &HA1
'---- In IDE
bIsNative = False
Case &HBA
'---- Psuedocode compiled
bIsNative = False
Case Else
'---- native code Compiled
' the actual byte might be any number of things
' because of optimizations in use
' but will generally be either &H55, &HC7 or &H83
bIsNative = True
End Select
End If
IsNative = bIsNative
End Function
Public Function IsIDE() As Boolean
'---- determine if we're running in environment
Static Inited As Boolean
Static bIsIDE As Boolean
Dim b As Byte
If Not Inited Then
CopyMemory b, ByVal pGetAddr(AddressOf pGetAddr), 1
'---- &HA1 means we're in the IDE, else we're not
bIsIDE = (b = &HA1)
End If
IsIDE = bIsIDE
End Function