Call CopyMemory(oDummy, l, 4) Set oThing = oDummy
CopyMemory should be defined like this:
Private Declare Sub CopyMemory Lib "kernel32" _ Alias "RtlMoveMemory" (pDest As Any, pSource As Any, _ ByVal ByteLen As Long)
The really neat thing here is that setting l doesn't add a reference to the object referenced by the argument of ObjPtr. Normally, when you set an object variable to point to an object, the object to which you point it (attach it, really) has its reference count incremented, meaning that the object can't be destroyed, because there are now two references to it. (This incrementing also happens if you pass the object as a parameter to a routine.) For an example of how this can hinder your cleanup of objects, see the discussion of the linked list example.
By using VarPtr (which yields the address of variables and UDTs), StrPtr (which yields the address of strings), and ObjPtr, you can create very real and very powerful and complex data structures.
Here's the short piece of code I used to discover that VarPtr, ObjPtr, and StrPtr are all pretty much the same thing (that is, the same function in a DLL):
Private Sub Form_Load() ' VB code to dump or match an external ' server method with a DLL entry point. Here it's ' used to dump the methods of the "_HiddenModule". ' Add a reference to 'TypeLib Information' (TLBINF32.DLL), ' which gives you TLI before running this code. Dim tTLInfo As TypeLibInfo Dim tMemInfo As MemberInfo Dim sDLL As String Dim sOrdinal As Integer Set tTLInfo = _ TLI.TLIApplication.TypeLibInfoFromFile("MSVBVM50.DLL") For Each tMemInfo In _ tTLInfo.TypeInfos.NamedItem("_HiddenModule").Members With tMemInfo tMemInfo.GetDllEntry sDLL, "", sOrdinal ' labDump is the label on the form where the ' output will be printed. labDump.Caption = labDump.Caption & _ .Name & _ " is in " & _ sDLL & _ " at ordinal reference " & sOrdinal & _ vbCrLf End With Next End Sub
The code uses TLBINF32.DLL, which can interrogate type libraries (very handy). Here I'm dumping some information on all the methods of a module (in type library parlance) named _HiddenModule. You'll see that this is the module that contains VarPtr, ObjPtr, and StrPtr, which you can discover using OLEVIEW.EXE to view MSVBVM60.DLL:
module _HiddenModule { [entry(0x60000000), vararg, helpcontext(0x000f6c9d)] VARIANT _stdcall Array([in] SAFEARRAY(VARIANT)* ArgList); [entry(0x60000001), helpcontext(0x000f735f)] BSTR _stdcall _B_str_InputB( [in] long Number, [in] short FileNumber); [entry(0x60000002), helpcontext(0x000f735f)] VARIANT _stdcall _B_var_InputB( [in] long Number, [in] short FileNumber); [entry(0x60000003), helpcontext(0x000f735f)] BSTR _stdcall _B_str_Input( [in] long Number, [in] short FileNumber); [entry(0x60000004), helpcontext(0x000f735f)] VARIANT _stdcall _B_var_Input( [in] long Number, [in] short FileNumber); [entry(0x60000005), helpcontext(0x000f65a4)] void _stdcall Width( [in] short FileNumber, [in] short Width); [entry(0x60000006), hidden] long _stdcall VarPtr([in] void* Ptr); [entry(0x60000007), hidden] long _stdcall StrPtr([in] BSTR Ptr); [entry(0x60000008), hidden] long _stdcall ObjPtr([in] IUnknown* Ptr); };
When you run the Visual Basic code, you'll see this output:
Label1Array is in VBA5.DLL at ordinal reference 601 _B_str_InputB is in VBA5.DLL at ordinal reference 566 _B_var_InputB is in VBA5.DLL at ordinal reference 567 _B_str_Input is in VBA5.DLL at ordinal reference 620 _B_var_Input is in VBA5.DLL at ordinal reference 621 Width is in VBA5.DLL at ordinal reference 565 VarPtr is in VBA5.DLL at ordinal reference 644 StrPtr is in VBA5.DLL at ordinal reference 644 ObjPtr is in VBA5.DLL at ordinal reference 644
This output shows the method name together with the DLL and ordinal reference (into the DLL) that implements its functionality. If you use DUMPBIN /EXPORTS on MSVBVM60.DLL like this:
dumpbin /exports msvbvm60.dll > dump
and then examine the dump file, you'll see that the routine at ordinal 644 is in fact VarPtr. In other words, VarPtr, ObjPtr, and StrPtr all do their stuff in the MSVBVM60.DLL routine VarPtr!
Matching the code output to the dump, we see this:
Method Name DLL Routine Name Label1Array rtcArray _B_str_InputB rtcInputCount _B_var_InputB rtcInputCountVar _B_str_Input rtcInputCharCount _B_var_Input rtcInputCharCountVar Width rtcFileWidth VarPtr VarPtr StrPtr VarPtr ObjPtr VarPtr
I haven't explained what the other routines do-you can discover that for yourself.
Stuff About Type Libraries
In this section, we'll take a quick look at type libraries-not those created by Visual Basic (because they're free) but those created by hand. You'll see how to use these handmade type libraries as development tools that will help you ensure that your coding standards are correctly applied.
A type library is where Visual Basic records the description of your ActiveX server's interfaces. Put another way, a type library is a file, or perhaps part of a file, that describes the type of one or more objects. (These objects don't have to be ActiveX servers.) Type libraries do not, however, store the actual objects described-they store only information about objects. (They might also contain immediate data such as constant values.) By accessing the type library, applications can check the characteristics of an object-that is, the object's exported and named interfaces.
When ActiveX objects are exported and made public in your applications, Visual Basic creates a type library for you to describe the object's interfaces. You can also create type libraries separately using the tools found on the Visual Basic 6 CD in \TOOLS\VB\UNSUPPRT\TYPLIB.
Type libraries are usually written using a language called Object Description Language (ODL) and are compiled using MKTYPLIB.EXE. A good way to learn a little more about ODL is to study existing type libraries. You can use the OLEVIEW.EXE tool mentioned earlier to disassemble type libraries from existing DLLs, ActiveX servers, and ActiveX controls for further study.
As I just said, the information described by a type library doesn't necessarily have anything to do with ActiveX. Here are a couple of handy examples to show how you might use type libraries.