実際、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 をビットマップ データへのポインターとして渡し、幅、高さ、ストライド、または C 関数でデータ形式を把握したいその他のパラメーターを渡します。上記の例では、各ピクセルに 4 バイト (3 バイト + 1 ダミー バイト) があるため、快適に処理できます。
bmp オブジェクトから処理されたデータを再利用するには、処理後に呼び出すだけです。
bmp.UnlockBits(bmpData);