2012-03-13 121 views
1

我试图编写一个C#包装Google's WebP encoder正确的C#PInvoke签名此WebP C++函数

的方法我尝试打电话是:

// 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's decoder wrapper我想出了以下内容:

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

不幸的是,每当我试图运行此我得到以下错误:

A call to PInvoke function 'WebPSharpLib!LibwebpSharp.Native.WebPEncoder::WebPEncodeRGB' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

我已经尝试了许多变化的签名到无avai湖

任何人都有线索?

干杯, 迈克

+0

删除最终的'IntPtr'参数上的'ref'。 – JaredPar 2012-03-13 23:13:41

+1

@JaredPar:不,不要。这是一个双重指针。 – SLaks 2012-03-13 23:14:34

+0

这些C++'int'的大小是多少? – SLaks 2012-03-13 23:15:00

回答

2

最有可能的原因的错误是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。由于size_t未签名,因此我也将使用UIntPtr作为返回类型。

您的代码可能存在更多问题,因为我们无法看到您是如何调用该函数的,我们也不知道该协议是用来调用它的。为了知道如何调用函数,您需要知道更多的功能签名。但是,我怀疑呼叫公约问题会让你过去当前的障碍。

+0

明白了!把我扔掉了,因为MC-KAY在他的DllImports上没有Cdecl – mikeysee 2012-03-13 23:46:02