实际上,我正在使用 CUDA 做与您提到的(图形过滤器)完全相同的操作。为了能够从托管代码 (WinForms) 调用 C 函数,我使用了 InteropServices。
假设您在一个解决方案中有 2 个项目 - C++ 库和一些 C# 项目。
要在 C++ 库中声明函数,我使用以下参数:
extern "C" int __declspec(dllexport) __stdcall cudaCopyInputData
(int n, int w, int h, byte* data)
{
inputBuffer = data;
bufferLength = n;
inputWidth = w;
inputHeight = h;
useFloatBuffer = 0;
binaryBufferValid = 0;
int bufferSize = bufferLength * sizeof(byte);
int floatBufferSize = bufferLength * sizeof(float);
int binaryBufferSize = w * h * sizeof(int);
cudaMalloc((void**)&cudaInputBuffer, bufferSize);
cudaMemcpy(cudaInputBuffer, inputBuffer, bufferSize, cudaMemcpyHostToDevice);
cudaMalloc((void**)&cudaFloatBuffer, floatBufferSize);
cudaMalloc((void**)&cudaBinaryBuffer, binaryBufferSize);
return 0;
}
为了能够从 C# 项目中使用它,我使用 InteropServices 将此函数作为静态方法导入:
[DllImport("CUDA Dll.dll", CharSet = CharSet.Ansi, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
public static extern int cudaCopyInputData(int n, int w, int h, IntPtr data);
然后,您可以从托管代码中将其用作标准方法。
要将位图数据传递给导入的方法,您可以使用如下内容:
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
然后将 bmpData.Scan0 作为指向位图数据的指针和一些其他参数(如 Width、Height、Stride 或任何您想在 C 函数中确定数据格式的参数)传递。在上面的示例中,每个像素将有 4 个字节(3 个字节 + 1 个虚拟字节),因此处理它很舒服。
要重用 bmp 对象中已处理的数据,您只需在处理后调用:
bmp.UnlockBits(bmpData);