How do I understand MashalAs

T

Tony Johansson

Hi!

How should I understand this with MarshalAs in this example ?
static extern void
GetSystemTime([MarshalAs(UnmanagedType.LPStruct)]MySystemTime st);

Is it correct to understand it in this way. When the managed code is excuted
we have type MySystemTime
but when the unmanaged type is called the type is changed to be LPStruct.

//Tony
 
P

Peter Duniho

Tony said:
Hi!

How should I understand this with MarshalAs in this example ?
static extern void
GetSystemTime([MarshalAs(UnmanagedType.LPStruct)]MySystemTime st);

Is it correct to understand it in this way. When the managed code is excuted
we have type MySystemTime
but when the unmanaged type is called the type is changed to be LPStruct.

I was just looking at this a few weeks ago. At the time, I ran across a
blog post, on MSDN I think, in which the author stated that the LPStruct
enumeration value is poorly named, because it's really only useful for
instances of System.Guid (talk about specialized!).

If it works at all with any other type, then the answer to your question
is "no". There's no such "unmanaged type" as "LPStruct". That's
meaningless to unmanaged code. Rather, it would mean that the unmanaged
code is passed a pointer to the struct itself.

But more likely, the author of the article was correct and you should
not use that enumeration value for anything except passing instances of
System.Guid.

A quick Google, and it turns out the article I remember is the very
first hit for my search:
http://blogs.msdn.com/adam_nathan/archive/2003/04/23/56635.aspx

I admit, I didn't find it the most illuminating article, but it did have
some useful information and warned me against bother to use LPStruct
with anything except System.Guid.

Pete
 
T

Tony Johansson

Peter Duniho said:
Tony said:
Hi!

How should I understand this with MarshalAs in this example ?
static extern void
GetSystemTime([MarshalAs(UnmanagedType.LPStruct)]MySystemTime st);

Is it correct to understand it in this way. When the managed code is
excuted we have type MySystemTime
but when the unmanaged type is called the type is changed to be LPStruct.

I was just looking at this a few weeks ago. At the time, I ran across a
blog post, on MSDN I think, in which the author stated that the LPStruct
enumeration value is poorly named, because it's really only useful for
instances of System.Guid (talk about specialized!).

If it works at all with any other type, then the answer to your question
is "no". There's no such "unmanaged type" as "LPStruct". That's
meaningless to unmanaged code. Rather, it would mean that the unmanaged
code is passed a pointer to the struct itself.

But more likely, the author of the article was correct and you should not
use that enumeration value for anything except passing instances of
System.Guid.

A quick Google, and it turns out the article I remember is the very first
hit for my search:
http://blogs.msdn.com/adam_nathan/archive/2003/04/23/56635.aspx

I admit, I didn't find it the most illuminating article, but it did have
some useful information and warned me against bother to use LPStruct with
anything except System.Guid.

Pete

If I take another example then.
So here it must be correct to say when the managed code is excuted
we have a string type but when the unmanaged type is called the type is
changed to be LPStr.
That must be corerct ?

[MarshalAs(UnmanagedType.LPStr)]
public string firstName;

//Tony
 
P

Peter Duniho

Tony said:
If I take another example then.
So here it must be correct to say when the managed code is excuted
we have a string type but when the unmanaged type is called the type is
changed to be LPStr.
That must be corerct ?

Only sort of.

IMHO, it is wrong to think of the marshaler as changing the type from
one thing to another. The type _is_ one thing in managed code, and _is_
another thing in unmanaged code.

Rather, the marshaler is interpreting the data on one side (e.g.
managed), and then translating it to the correct format for the other
side (e.g. unmanaged). It's not the same object on one side as the
other, so it doesn't make sense to think of the type of the object as
having been changed.

That said, the unmanaged Windows API does include a definition of a
string type called "LPSTR", and using the UnmanagedType.LPStr
enumeration value does inform the marshaler to translate a managed
System.String instance to a new unmanaged LPSTR instance (and back again
if necessary).

I don't happen to think that the translation is the same as literally
changing the type of some data, but if you do think of it that way, then
yes…that's what it does.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top