How to Resolve Error "CS0635: System.Interop.UnmanagedType.CustomMarshaler requires named arguments MarshalType and MarshalCookie" in C#
The Compiler Error CS0635 is a configuration error related to Interop (interoperability with unmanaged code). The message reads: "'Attribute' : System.Runtime.InteropServices.UnmanagedType.CustomMarshaler requires named arguments MarshalType and MarshalCookie".
The exact error message usually asks for MarshalType, MarshalTypeRef, or MarshalCookie, though older documentation might refer to ComType.
When you use the [MarshalAs(UnmanagedType.CustomMarshaler)] attribute, you are telling the CLR: "I have written a custom class to handle the conversion of this specific parameter." However, simply saying "Use a custom marshaler" is not enough. You must explicitly tell the CLR which class to use as the marshaler and (optionally) provide a "cookie" string to configure it. Without these named arguments, the attribute is incomplete.
Understanding Custom Marshaling
Standard marshaling handles common types (e.g., converting string to LPStr). Custom marshaling allows you to write a class that implements ICustomMarshaler to handle complex or non-standard conversions between .NET (Managed) and C++ (Unmanaged) memory.
To wire this up, you apply the attribute to a field or parameter:
[MarshalAs(UnmanagedType.CustomMarshaler)]
This declaration is logically incomplete without answering the question: "Which Custom Marshaler?"
Scenario: The Incomplete Attribute
This error occurs when you select UnmanagedType.CustomMarshaler but forget to provide the mandatory named properties that identify your custom class.
Example of error:
using System;
using System.Runtime.InteropServices;
public class NativeMethods
{
// ⛔️ Error CS0635: UnmanagedType.CustomMarshaler requires named arguments.
// The compiler doesn't know which class contains the marshaling logic.
[DllImport("MyLib.dll")]
public static extern void DoWork(
[MarshalAs(UnmanagedType.CustomMarshaler)] object data
);
}
Solution: Specify MarshalType or MarshalTypeRef
You must provide one of the two identification properties:
MarshalTypeRef: TheSystem.Typeof your custom marshaler class (Recommended, strongly typed).MarshalType: The fully qualified string name of the class (Error-prone due to typos).
Prerequisite: A Custom Marshaler Class
First, ensure you have a class that implements ICustomMarshaler.
public class MyCustomMarshaler : ICustomMarshaler
{
// Singleton pattern is required for custom marshalers
private static MyCustomMarshaler _instance = new MyCustomMarshaler();
public static ICustomMarshaler GetInstance(string cookie) => _instance;
public object MarshalNativeToManaged(IntPtr pNativeData) => null;
public IntPtr MarshalManagedToNative(object ManagedObj) => IntPtr.Zero;
public void CleanUpNativeData(IntPtr pNativeData) { }
public void CleanUpManagedData(object ManagedObj) { }
public int GetNativeDataSize() => -1;
}
Solution: Linking the Class
Now update the MarshalAs attribute to point to MyCustomMarshaler.
public class NativeMethods
{
[DllImport("MyLib.dll")]
public static extern void DoWork(
// ✅ Correct: We explicitly tell the CLR to use 'MyCustomMarshaler'
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(MyCustomMarshaler))]
object data
);
}
Advanced: Using MarshalCookie
The error message might also mention MarshalCookie (or Cookie in some contexts). While often optional, this is a string argument passed to your marshaler's GetInstance(string cookie) method. It allows you to reuse one marshaler logic for slightly different scenarios.
Even if you don't need a cookie, the error implies that the syntax structure for CustomMarshaler expects these named parameters.
public class NativeMethods
{
[DllImport("MyLib.dll")]
public static extern void DoWork(
[MarshalAs(UnmanagedType.CustomMarshaler,
MarshalTypeRef = typeof(MyCustomMarshaler),
MarshalCookie = "SpecialMode")] // Passed to GetInstance()
object data
);
}
Conclusion
CS0635 is a missing configuration error.
- Check the Type: Did you use
UnmanagedType.CustomMarshaler? - Provide the Link: You must add
, MarshalTypeRef = typeof(MyClass)inside the attribute parentheses. - Check the Class: Ensure the class you reference actually implements
ICustomMarshaler.