将C#代码转C++/CLI时,托管对象句柄与Lambda表达式报错问题
C# SkiaSharp代码转C++/CLI的InstallPixels回调问题解决
错误原因分析
第一种写法的错误
- 委托类型不匹配:
InstallPixels要求的是SKBitmapReleaseDelegate类型(签名为void(IntPtr, Object^)),但你用了Action<GCHandle>,签名完全不符。 - 委托初始化错误:静态方法的委托不需要传递实例对象(第一个参数应为
nullptr),且你错误地将GCHandle作为委托构造参数传入,正确做法是将其作为context参数传递给InstallPixels。 - 值类型误用
gcnew:SKImageInfo是值类型,无需用gcnew分配托管堆对象,直接声明栈实例即可。
第二种写法的错误
- 不必要的
gcroot:gcroot用于在非托管代码中持有托管引用,此处纯托管环境下不需要,直接使用GCHandle即可。 - 成员访问符号错误:
gcroot<GCHandle>是值类型,访问成员需用.而非->。 - Lambda签名不匹配:Lambda未匹配
SKBitmapReleaseDelegate的双参数签名。
正确实现代码
方法1:静态回调方法+Context传递GCHandle
#include <SkiaSharp.h> using namespace System::Runtime::InteropServices; using namespace SkiaSharp; static void ReleasePixelBuffer(IntPtr pixels, System::Object^ context) { // 将context转换回GCHandle并释放 GCHandle handle = safe_cast<GCHandle>(context); handle.Free(); } static void Test() { // 创建输出位图 SKBitmap^ bitmap = gcnew SKBitmap(); // SKImageInfo是值类型,直接栈上声明 SKImageInfo info(input.cols, input.rows, SKColorType::Bgra8888); // 创建像素缓冲区 array<System::Byte>^ buffer = gcnew array<System::Byte>(input.cols * input.rows * 4); GCHandle outputPtr = GCHandle::Alloc(buffer, GCHandleType::Pinned); // 调用InstallPixels,传递正确的委托和context bitmap->InstallPixels( info, outputPtr.AddrOfPinnedObject(), info.RowBytes, gcnew SKBitmapReleaseDelegate(&ReleasePixelBuffer), GCHandle::ToObject(outputPtr) // 将GCHandle包装为Object作为上下文传递 ); }
方法2:Lambda表达式(C++/CLI支持捕获式Lambda转委托)
#include <SkiaSharp.h> using namespace System::Runtime::InteropServices; using namespace SkiaSharp; static void Test() { SKBitmap^ bitmap = gcnew SKBitmap(); SKImageInfo info(input.cols, input.rows, SKColorType::Bgra8888); array<System::Byte>^ buffer = gcnew array<System::Byte>(input.cols * input.rows * 4); GCHandle outputPtr = GCHandle::Alloc(buffer, GCHandleType::Pinned); // 使用匹配签名的Lambda作为回调,直接捕获GCHandle bitmap->InstallPixels( info, outputPtr.AddrOfPinnedObject(), info.RowBytes, gcnew SKBitmapReleaseDelegate([outputPtr](IntPtr pixels, System::Object^) { outputPtr.Free(); }), nullptr ); }
内容的提问来源于stack exchange,提问作者MrEighteen
相关产品推荐
相关产品推荐

