In marshalasattribute, the first parameter type is the unmanagedtype enumeration to specify the corresponding unmanaged data type. In this enumeration type, there are two very strange values: unmanaged. lpstruct and unmanagedtype. struct. The two enumeration values are described in the msdn document as follows:
Struct |
A variant, which is used to marshal managed formatted classes and value types. |
Lpstruct |
A pointer to a C-style structure that you use to manage Al managed formatted classes. Valid for platform invoke methods only. |
First, struct. marshalas (unmanagedtype. struct) does not actually specify marshal as variant. Financialas (unmanagedtype. struct) applies to most value types and object types (excluding other reference types). In both cases, there is no difference between writing and not writing. When used for value type, CLR converts the corresponding value type to the corresponding unmanaged type. When used for the object type, CLR converts the object to variant. The latter case is clearly inaccurate. In fact, do not write marshalas (unmanagedtype. struct) there is basically no difference, and there is no help for readability, but the complexity is increased due to document errors and two different situations, so it is best not to use this enumeration value.
What is strange is lpstruct, which is literally a pointer to struct. In fact, this enumeration can only be used in two cases:
1. guid and decimal
The role here is to tell CLR to add more references. For example, the unmanaged type corresponding to the guid is guid, And the unmanaged type corresponding to the [financialas (unmanagedtype. lpstruct)] GUID is guid *, which requires multiple level-1 pointers. This helps you avoid using ref GUID (the corresponding unmanaged type is also guid *), which makes the function prototype look more natural, in particular, guid * is only used for input. In other cases, you can use the [financialas (unmanagedtype. lpstruct)] ref guid statement to pass the guid **.
2. Generally, the reference type is class. Except for reference types that are closely related to the system, such as string, stringbuilder, array, and delegate.
Unlike guid/decimal, in this case, there is no difference between writing and not writing, because the class itself is passed by reference and has a level-1 pointer. For example:
The corresponding unmanaged type is myclass *.
It can be seen that there is no error in the document itself, but it basically does not help the author.
Because the lpstruct enumeration value does not affect readability, and the behavior is different under different circumstances (but it can be considered to be consistent, but it is slightly difficult to understand), the document itself is not clearly used. For these reasons, it is likely that the CLR InterOP team will gradually stop supporting lpstruct in the future. My advice is to try not to use lpstruct in the program.
Author:Atfield) |
Blog:Http://blog.csdn.net/atfield |
Email:Atfield_zhang@hotmail.com |
Reprinted please indicate the source |