Правильная подпись C# PInvoke для этой функции WebP C++

StackOverflow https://stackoverflow.com//questions/9693620

  •  13-12-2019
  •  | 
  •  

Вопрос

Я пытаюсь написать оболочку C# для Кодер Google WebP.

Метод, который я пытаюсь вызвать:

// Returns the size of the compressed data (pointed to by *output), or 0 if
// an error occurred. The compressed data must be released by the caller
// using the call 'free(*output)'.
WEBP_EXTERN(size_t) WebPEncodeRGB(const uint8_t* rgb,
                              int width, int height, int stride,
                              float quality_factor, uint8_t** output);

Заимствование у оболочка декодера Mc-Kay Я придумал следующее:

[DllImport("libwebp", CharSet = CharSet.Auto)]
public static extern IntPtr WebPEncodeRGB(IntPtr data, int width, int height, int stride, float quality, ref IntPtr output);

К сожалению, всякий раз, когда я пытаюсь запустить это, я получаю следующую ошибку:

Вызов функции PInvoke «WebPSharpLib!LibwebpSharp.Native.WebPEncoder::WebPEncodeRGB» привел к разбалансировке стека.Вероятно, это связано с тем, что управляемая подпись PInvoke не соответствует неуправляемой целевой подписи.Убедитесь, что соглашение о вызовах и параметры подписи PInvoke соответствуют целевой неуправляемой подписи.

Я пробовал много вариантов подписи, но безрезультатно.

Кто-нибудь знает?

Ура, Майк

Это было полезно?

Решение

Наиболее вероятная причина ошибки в том, что код C++ использует cdecl соглашение о вызовах, но ваш pinvoke использует stdcall соглашение о вызовах.Измените pinvoke следующим образом:

[DllImport("libwebp", CallingConvention=CallingConvention.Cdecl)]
public static extern UIntPtr WebPEncodeRGB(IntPtr data, int width, int height, 
    int stride, float quality, ref IntPtr output);

Нет необходимости указывать CharSet для функции, которая не имеет текстовых параметров.Я бы также использовал UIntPtr в качестве типа возвращаемого значения, поскольку size_t не подписан.

С вашим кодом могут возникнуть дополнительные проблемы, поскольку мы не видим, как вы вызываете функцию, а также не знаем, какой протокол используется для ее вызова.Вам нужно знать больше, чем просто сигнатуру функции, чтобы знать, как вызвать функцию.Однако я подозреваю, что проблема соглашения о вызовах поможет вам преодолеть нынешнее препятствие.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top