Search code examples
c#juliamarshallingdllimport

C# Custom Marshaling - ICustomMarshaler implementation not supplied with zero IntPtr values


I've implemented a very simple custom marshaler for an API:

Custom Marshaler:

  private sealed class JuliaWrapperMarshaller : ICustomMarshaler
  {
      object ICustomMarshaler.MarshalNativeToManaged(IntPtr pNativeData) => (JuliaWrapper)pNativeData;

     [other methods removed]  
  }

API:

    [DllImport(@"libjulia.dll", CallingConvention = CallingConvention.Cdecl)]
    [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(JuliaWrapperMarshaller))]
    public static extern JuliaWrapper jl_eval_string(string str);

And this works fine when the jl_eval_string method returns a non-zero IntPtr. I can convert it to my return object JuliaWrapper and all is well.


The problem comes when I execute jl_eval_string with invalid parameters and it returns a zero IntPtr.

I want to handle this in my JuliaWrapper object and automatically call 'get last error'. However I don't get the chance to, because the ICustomMarshaler.MarshalNativeToManaged method is never invoked when the jl_eval_string method returns 0x0000

  • Is there a way of telling the custom marshaler to provide me with 0 IntPtr values?
  • Are there any hacks to work around this?
  • Is there a better way of working?

Solution

  • Based on Hans' comment, this isn't possible.

    In order to achieve similar functionality, I created public/private shadow functions which return my wrapper class.

    enter image description here

    The implicit operator function receives the IntPtr which is 0 or otherwise, and calls the constructor of my wrapper class, which I then have code in to handle calling 'GetLastError' if the IntPtr is 0.

    enter image description here