C # Custom Marshaling - реализация ICustomMarshaler не поставляется с нулевыми значениями IntPtr - PullRequest
1 голос
/ 30 мая 2019

Я реализовал очень простой пользовательский маршалер для API:

Пользовательский маршалер:

  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);

И это прекрасно работает, когда метод jl_eval_string возвращает ненулевой IntPtr. Я могу преобразовать его в свой возвращаемый объект JuliaWrapper, и все хорошо.


Проблема возникает, когда я выполняю jl_eval_string с недопустимыми параметрами, и он возвращает нулевой IntPtr.

Я хочу обработать это в моем JuliaWrapper объекте и автоматически вызвать 'get last error'. Однако у меня нет возможности , потому что метод ICustomMarshaler.MarshalNativeToManaged никогда не вызывается, когда метод jl_eval_string возвращает 0x0000

  • Есть ли способ сообщить пользовательскому маршалеру предоставить мне 0 значений IntPtr?
  • Есть ли какие-нибудь хаки, чтобы обойти это?
  • Есть ли лучший способ работы?

1 Ответ

1 голос
/ 30 мая 2019

Судя по комментариям Ганса, это невозможно.

Для достижения аналогичной функциональности я создал открытые / закрытые теневые функции, которые возвращают мой класс-оболочку.

enter image description here

Функция implicit operator получает IntPtr, равный 0 или иным образом, и вызывает конструктор моего класса-оболочки, который затем содержит код для обработки вызова GetLastError, если IntPtr равен 0.

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...