I am working on a Windows Runtime <-> Rust integration through windows-rs. The interface between the two languages is done trough an .idl (Midl 3.0) file.
I am trying to declare a parameter as a nullable string.
The documentation specifies
For each non-nullable value type T (except String), there’s a corresponding nullable type Windows.Foundation.IReference, which can hold the additional value null.
So it seems that for every value type (apart from String
) I can use IReference
for nullable and any reference type is nullable by default. Both of these would translate to an Option
on the Rust side.
It seems that the only type1 that cannot be nullable is String
. If you try IReference<String>
you will get this MIDL error:
error MIDL5037 : [msg]Invalid parameter to IReference or IReferenceArray
If your parameter type is String
, when you try to pass a null
from C#, you’d get
System.ArgumentNullException: Value cannot be null
There is a workaround though, it’s to create a struct
(or a runtime class) wrapping a String
:
struct OptionalString {
String value;
};
Then you can do IReference<OptionalString>
. This works because the rule is “any value type apart from String”, and structs containing strings do not match the exception.
I can’t wrap my head around why you can have any1 parameter as optional, excepted if (and only if) it’s a string. Is this a flaw of Midl
, or is there a way to do this without a workaround?
1 I stand corrected, it’s not only String. It looks like you cannot have nullable arrays either. If you use IReference<Type[]>
, then you’ll get a syntax error. But I believe nullable arrays are a less common use case (at least for me).