You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I wanted to write a custom string marshaller that was generic across multiple of our libraries. They all have their own free() functions, so I wanted to inject a type to allow me to pass extra data to the marshaller.
[CustomMarshaller(typeof(string), MarshalMode.ManagedToUnmanagedOut,typeof(LengthStringMarshaller<,>))][ContiguousCollectionMarshaller]publicstaticunsafeclassLengthStringMarshaller<TFree,TUnmanagedElement>whereTUnmanagedElement: unmanaged
whereTFree:ILengthStringFree<TUnmanagedElement>{publicstaticstringAllocateContainerForManagedElements(TUnmanagedElement*unmanaged,intnumElements){if(unmanaged isnull)return"";if(typeof(TUnmanagedElement)!=typeof(byte)){thrownew InvalidOperationException("TUnmanagedElement must be byte");}stringret= Encoding.UTF8.GetString((byte*)unmanaged, numElements);
TFree.FreeString(unmanaged, numElements);returnret;}
...}
I don't control either managed (string) or unmanaged (byte), so I can't attach the free function to either of those types using static interfaces. But this doesn't work, because the marshaller expects the generic arity to be N + 1 exactly. It expects that because NativeMarshallingAttribute requires N + 1
Talking to @jkoritzinsky, this could be a case where we could downgrade that error to a warning assuming the managed type is non generic, and again downgrade from warning to nothing if the managed type is defined in another assembly.
The text was updated successfully, but these errors were encountered:
Tagging subscribers to this area: @dotnet/interop-contrib
See info in area-owners.md if you want to be subscribed.
Issue Details
I wanted to write a custom string marshaller that was generic across multiple of our libraries. They all have their own free() functions, so I wanted to inject a type to allow me to pass extra data to the marshaller.
[CustomMarshaller(typeof(string), MarshalMode.ManagedToUnmanagedOut, typeof(LengthStringMarshaller<,>))]
[ContiguousCollectionMarshaller]
public static unsafe class LengthStringMarshaller<TFree, TUnmanagedElement> where TUnmanagedElement : unmanaged
where TFree : ILengthStringFree<TUnmanagedElement>
{
public static string AllocateContainerForManagedElements(TUnmanagedElement* unmanaged, int numElements)
{
if (unmanaged is null)
return "";
if (typeof(TUnmanagedElement) != typeof(byte))
{
throw new InvalidOperationException("TUnmanagedElement must be byte");
}
string ret = Encoding.UTF8.GetString((byte*)unmanaged, numElements);
TFree.FreeString(unmanaged, numElements);
return ret;
}
...
}
I don't control either managed (string) or unmanaged (byte), so I can't attach the free function to either of those types using static interfaces. But this doesn't work, because the marshaller expects the generic arity to be N + 1 exactly. It expects that because NativeMarshallingAttribute requires N + 1
Talking to @jkoritzinsky, this could be a case where we could downgrade that error to a warning assuming the managed type is non generic, and again downgrade from warning to nothing if the managed type is defined in another assembly.
I wanted to write a custom string marshaller that was generic across multiple of our libraries. They all have their own free() functions, so I wanted to inject a type to allow me to pass extra data to the marshaller.
I don't control either managed (string) or unmanaged (byte), so I can't attach the free function to either of those types using static interfaces. But this doesn't work, because the marshaller expects the generic arity to be N + 1 exactly. It expects that because NativeMarshallingAttribute requires N + 1
Talking to @jkoritzinsky, this could be a case where we could downgrade that error to a warning assuming the managed type is non generic, and again downgrade from warning to nothing if the managed type is defined in another assembly.
The text was updated successfully, but these errors were encountered: