使用ffi发送c++字节数据以进行flutter



我在这个链接中使用了这段代码,使用GdiPlus拍摄了屏幕截图,并将位图转换为png字节

#include <iostream>
#include <fstream>
#include <vector>
#include <Windows.h>
#include <gdiplus.h>
bool save_png_memory(HBITMAP hbitmap, std::vector<BYTE>& data)
{
Gdiplus::Bitmap bmp(hbitmap, nullptr);
//write to IStream
IStream* istream = nullptr;
if (CreateStreamOnHGlobal(NULL, TRUE, &istream) != 0)
return false;
CLSID clsid_png;
if (CLSIDFromString(L"{557cf406-1a04-11d3-9a73-0000f81ef32e}", &clsid_png)!=0)
return false;
Gdiplus::Status status = bmp.Save(istream, &clsid_png);
if (status != Gdiplus::Status::Ok)
return false;
//get memory handle associated with istream
HGLOBAL hg = NULL;
if (GetHGlobalFromStream(istream, &hg) != S_OK)
return 0;
//copy IStream to buffer
int bufsize = GlobalSize(hg);
data.resize(bufsize);
//lock & unlock memory
LPVOID pimage = GlobalLock(hg);
if (!pimage)
return false;
memcpy(&data[0], pimage, bufsize);
GlobalUnlock(hg);
istream->Release();
return true;
}
int main()
{
CoInitialize(NULL);
ULONG_PTR token;
Gdiplus::GdiplusStartupInput tmp;
Gdiplus::GdiplusStartup(&token, &tmp, NULL);
//take screenshot
RECT rc;
GetClientRect(GetDesktopWindow(), &rc);
auto hdc = GetDC(0);
auto memdc = CreateCompatibleDC(hdc);
auto hbitmap = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
auto oldbmp = SelectObject(memdc, hbitmap);
BitBlt(memdc, 0, 0, rc.right, rc.bottom, hdc, 0, 0, SRCCOPY);
SelectObject(memdc, oldbmp);
DeleteDC(memdc);
ReleaseDC(0, hdc);
//save as png
std::vector<BYTE> data;
if(save_png_memory(hbitmap, data))
{
//write from memory to file for testing:
std::ofstream fout("test.png", std::ios::binary);
fout.write((char*)data.data(), data.size());
}
DeleteObject(hbitmap);
Gdiplus::GdiplusShutdown(token);
CoUninitialize();
return 0;
}

问题

  • 如何准备字节数据(std::vector data;(以使其通过dart-ffi,从而在flutter中使用它
  • 请尽可能接受

我最大的困惑是ffi没有对应的字节数据类型,那么我应该如何处理它呢?

您在Dart端查找的数据类型是Pointer<Uint8>,它是指向无符号字节的指针。您可以通过ffi边界传递此指针,并访问任意一侧的指针对象字节。但是,在您分配一些存储之前(想想malloc/free(,指针对您没有好处。

有两种方法可以分配指针将引用的存储(字节数组(。您可以在C端使用malloc(随后使用free(字节,也可以在Dart端使用malloc.allocate<Uint8>()(随后使用malloc.free()(字节。

然后,在C端,您的代码片段中已经有了用于将std::vector<BYTE>复制到指针缓冲区的示例代码:

memcpy(&data[0], the_pointer, bufsize);

将CCD_ 9字节从CCD_。(或者,只要知道数据不会超出范围,就可以将&data[0]分配给指针,并在使用后释放它(。

一旦您在Dart端有了Pointer<Uint8>,只需调用asTypedList即可获得一个允许您访问Dart端字节的Uint8List

此外,请记住Dart FFI是一个C接口,因此如果您想使用C++类,则需要将它们封装在C方法中。请参阅:我可以在dart-ffi中调用C++构造函数吗?这些C方法可以/应该在C++源文件中,只要它们被标记为extern "C"

最新更新