Add Out and Ref support for AnsiString and UnicodeString#3208
Add Out and Ref support for AnsiString and UnicodeString#3208shrah merged 1 commit intodotnet:masterfrom
Conversation
| public static unsafe string UnicodeBufferToString(char* buffer) | ||
| { | ||
|
|
||
| if (buffer == null) |
There was a problem hiding this comment.
Why not just return new String(buffer);?
yizhang82
left a comment
There was a problem hiding this comment.
LGTM modulo comments. Thanks!
| { | ||
| get | ||
| { | ||
| return true; |
There was a problem hiding this comment.
It should be only required if we don't pin.
| // Marshalling a null string? | ||
| codeStream.Emit(ILOpcode.brfalse, lNullString); | ||
| // Marshalling a null string? | ||
| codeStream.Emit(ILOpcode.brfalse, lNullString); |
| StoreManagedValue(codeStream); | ||
| } | ||
|
|
||
| protected override void EmitCleanupManagedToNative(ILCodeStream codeStream) |
There was a problem hiding this comment.
You might want to change this to EmitCleanupManaged/EmitCleanupNative. It's easier to understand that way.
|
|
||
| protected override void EmitCleanupManagedToNative(ILCodeStream codeStream) | ||
| { | ||
| if (!ShouldBePinned) |
There was a problem hiding this comment.
You should make sure ShouldCleanup returns the right value - and you wouldn't have to special case here
| { | ||
| get | ||
| { | ||
| return MarshallerType != MarshallerType.Field |
There was a problem hiding this comment.
This is missing a few cases. See our ilmarshallers.cpp:
bool ILWSTRMarshaler::CanUsePinnedManagedString(DWORD dwMarshalFlags)
{
LIMITED_METHOD_CONTRACT;
return IsCLRToNative(dwMarshalFlags) && !IsByref(dwMarshalFlags) && IsIn(dwMarshalFlags) && !IsOut(dwMarshalFlags);
}
|
|
||
| int stringLength = str.Length; | ||
|
|
||
| if (stringLength == 0) |
There was a problem hiding this comment.
This is not correct. Empty string is not a null string. It should be a buffer '\0'.
| } | ||
|
|
||
| char* buffer = (char*)PInvokeMarshal.CoTaskMemAlloc((UIntPtr)(sizeof(char) * (stringLength+1))).ToPointer(); | ||
| for (int i = 0; i < stringLength; i++) |
There was a problem hiding this comment.
Is there a better copy operation? Buffer.copy?
| unsigned short *p = expected; | ||
| unsigned short *q = *val; | ||
|
|
||
| while (*p && *q && *p == *q) |
There was a problem hiding this comment.
extract this into a helper?
| return; | ||
|
|
||
| char *p = dst, *q = src; | ||
| while (*q) |
| private static extern int VerifyAnsiString(string str); | ||
|
|
||
| [DllImport("*", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] | ||
| private static extern int VerifyAnsiStringOut(out string str); |
There was a problem hiding this comment.
Another interesting case you might want to consider: [in] ref
There was a problem hiding this comment.
Added a case with [in] ref
No description provided.