Unofficial VarPtr, StrPtr, and ObjPtr migration to C#

6. January 2009 09:46 by Mrojas in General  //  Tags:   //   Comments (0)

These interesting functions have a long history, since the BASIC language, QuickBasic
and earlier versions of Visual Basic.  There isn’t much documentation on them but you
can look at very good reference as the one published by Matthew Curland
titled Unofficial Documentation for VarPtr, StrPtr, and ObjPtr

Well enough history, now let’s get back to the the migration part. If you’re reading this
post it might be, because you have VarPtr, StrPtr or ObjPtr calls in your code and you
want to move those calls to C#.

Well we have good and bad news.

Bad news are that the .NET world is a lot different than VB. Remember that your code
is running in the managed sandbox, and to get the address of variable you are probably
dealing with unmanaged memory, so some things might not work.

Good news are that I am one of those that believe that there are no imposibles,
it’s just a matter of the cost of developing the solution :)

Let’s see at some alternatives:

VarPtr can be use to get pointers to vaiables. This can be solved using Unsafe code:

VB6

  Dim l As Long
  Debug.Print VarPtr(l)

C#

    class Program
    {
        [DllImport(@"DllTest1.Dll")]
        static extern void Foo(IntPtr p);
        static void Main(string[] args)
        {
            int l;
            unsafe
            {
                int* pointerToL = &l;
                Foo((IntPtr)pointerToL);
                // Print the address stored in pointerToL:
                System.Console.WriteLine(
"The address stored in pointerToL: {0}", (int)pointerToL); } } }
And The implementation for Foo is a C function like:
extern "C" 
{
__declspec(dllexport)  void Foo(int* data)
{
    *data = 100;
}
}
Unsafe code like this will work for VarPtr cases where you have primitive types, 
like int, short, char variables.
Structures are more tricky and you will require pinning the memory to avoid some 
other problems. But in general doing Interop with structures is very tricky and
I will publish another post about this.
Unsafe code must be enabled at the assembly level and the assembly might need to 
be signed.
StrPtr is very similar to VarPtr but it mostly to provide efficient marshalling 
to Unicode functions. In most of cases like:
  Declare Sub MyUnicodeCall Lib "MyUnicodeDll.Dll" _
      (ByVal pStr As Long)

   Sub MakeCall(MyStr As String)
      MyUnicodeCall StrPtr(MyStr)
   End Sub
The StrPtr declaration is no longer needed because the .NET Interop mechanism can 
handle most of this marshaling automatically.
ObjPtr is the most tricky of all because it can be used in COM scenarios to get 
pointers to Interfaces implemented by a class.
In .NET scenarios this will involve only using classes that are exposed by COM. 
I have use code as the following
for some of those cases:
            Object myComObject = null;
            //..init code
            IntPtr pIUnknown = Marshal.GetIUnknownForObject(myComObject);
            IntPtr pIDesiredInterface = IntPtr.Zero;
            Guid guidToDesiredInterface = new Guid("XXXXXXXX-XXXX-XXXX");
            Marshal.QueryInterface(pIUnknown, 
ref guidToDesiredInterface,out pIDesiredInterface);

As always there are exceptions to the rule. These are just some general solutions. 
Directly accessing the memory is really something not desirable in a .NET application and in most
cases you should remove that code for something else, but if you can’t I hope these examples
guide you in this process.