[Mono-dev] GetAddrOf mono-basic vb.net

Rolf Bjarne Kvinge rolflists at ya.com
Sun May 6 10:57:31 EDT 2007

> -----Original Message-----
> From: mono-devel-list-bounces at lists.ximian.com [mailto:mono-devel-list-
> bounces at lists.ximian.com] On Behalf Of Jonathan Gilbert
> Sent: sábado, 05 de mayo de 2007 20:20
> To: mono-devel-list at lists.ximian.com
> Subject: Re: [Mono-dev] GetAddrOf mono-basic vb.net
> At 05:00 PM 5/4/2007 +0200, Rolf Bjarne wrote:
> >
> >>It is in VB6.
> >>Public Declare Function GetAddrOf Lib "kernel32" Alias "MulDiv"
> (nNumber As
> >>Any, Optional ByVal nNumerator As Long = 1, Optional ByVal
> nDenominator As
> >>Long = 1) As Long
> >
> >The VB.Net version should be something like
> >Public Declare Function GetAddrOf Lib "kernel32" Alias "MulDiv" (ByVal
> >nNumber As Integer, Optional ByVal Numerator As Integer = 1, Optional
> ByVal
> >Denominator As Integer = 1) As Integer
> >
> >At least according to the declaration of MulDiv in MSDN.
> >
> >Now why do you rename a function called MulDiv to GetAddrOf?
> What it is is an ingenious use of an API function to achieve something
> the
> original author thought VB didn't have built-in. (The original author
> should be directed to the help file pages for VarPtr, StrPtr and
> ObjPtr.)

Man, it's been too long since I wrote VB6 code... and I definitively forgot
how incredibly bad some of it can be.

> In VB6, as I mentioned, there is a built-in function to do this: VarPtr
> (or StrPtr if you want the string data of a String (which is just a BSTR
> VB6), or ObjPtr if you want a pointer to the interface you have
> selected for a given object reference).

Once upon a time I knew these functions, another reason why I didn't get the
need for GetAddrOf...

> In VB.NET, the idiom is, for the most part, completely unneeded,
> if you are hoping to write code that runs both on Windows and on other
> platforms in Mono. The only situation I can think of where you would
> directly need the memory address of data is where you have an unmanaged
> structure which has a member that points at the data, a structure which
> you would then pass into some system-specific API function.

> I'm no VB.NET expert; in C#, you would simply write an unsafe code
> block and use the address-of operator '&' to get your pointer (using
> for arrays). Perhaps there is a better way, but if you *really* need to
> pass a value by its memory address in VB.NET, all that comes to my mind
> be to use Marshal.AllocHGlobal, store the resulting IntPtr in the
> unmanaged structure, and then use Marshal.WriteInt32 (or one of its
friends) to
> fill the data at the memory address you just allocated.

If the allocated memory is supposed to be a structure, you can declare the
structure as managed and get the pointer to the structure using
Marshal.StructureToPtr and put that pointer into the first structure. If
it's a string you can put it directly in the first structure and decorate it
with the corresponding MarshalAs attribute. If it's just a big chunk of
memory you can use a byte array directly in the structure... You can almost
always come up with a satisfying solution.

More information about the Mono-devel-list mailing list