Правильная подпись C # PInvoke для этой функции WebP C ++ - PullRequest
1 голос
/ 14 марта 2012

Я пытаюсь написать оболочку 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 соответствуют целевой неуправляемой подписи.

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

Кто-нибудь получил подсказку?

Ура, Майк

1 Ответ

2 голосов
/ 14 марта 2012

Скорее всего, причиной ошибки является то, что код C ++ использует cdecl соглашение о вызовах, но ваш пинвоук использует 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 без знака.

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

...