Правильная подпись C# PInvoke для этой функции WebP C++
Вопрос
Я пытаюсь написать оболочку 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
не подписан.
С вашим кодом могут возникнуть дополнительные проблемы, поскольку мы не видим, как вы вызываете функцию, а также не знаем, какой протокол используется для ее вызова.Вам нужно знать больше, чем просто сигнатуру функции, чтобы знать, как вызвать функцию.Однако я подозреваю, что проблема соглашения о вызовах поможет вам преодолеть нынешнее препятствие.