我正在尝试编写一个 C# 包装器 谷歌的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