C # Something to interact with c ++,
Recently, when I was working on a project, the other company provided only one c ++ DLL, but it was not blocked. c # could not be DllImport. Therefore, I had to write c ++ to block it myself.
The Dll of the other party only receives the yuv420 image format. Therefore, opencv is used for conversion in c ++. I wanted to write C #, but I always felt trouble.
[C #] Code
Public void Do (Bitmap bp)
{
Bitmap outIMG = new Bitmap (bp. Width, bp. Height );
System. drawing. imaging. bitmapData bmp data = bp. lockBits (new System. drawing. rectangle (0, 0, bp. width, bp. height), System. drawing. imaging. imageLockMode. readWrite,
Bp. PixelFormat );
System. drawing. imaging. bitmapData BMP data1 = outIMG. lockBits (new System. drawing. rectangle (0, 0, outIMG. width, outIMG. height), System. drawing. imaging. imageLockMode. readWrite,
OutIMG. PixelFormat );
CFunction (BMP data. Scan0, bp. Width, bp. Height, 3, 0, BMP data1.scan0 );
Img. UnlockBits (BMP data );
OutIMG. UnlockBits (BMP data1 );
}
[C ++] Code
Extern "C" _ declspec (dllexport) void WINAPI CFunction (unsigned char * img, int width, int height, int ch, int format, unsigned char * outImg)
{
Mat frame (Size (width, height), CV_8UC (ch), img );
Mat dest;
CvtColor (frame, dest, format = 0? CV_BGR2YUV_I420: CV_RGB2YUV_I420 );
Third-party Dll (dest );
Mat rgb;
CvtColor (dest, rgb, format = 0? CV_YUV2BGR_I420: CV_YUV2RGB_I420 );
Memcpy (void *) outImg, (void *) dest. data, rgb. cols * rgb. rows * rgb. channels ());
}
This basically realizes the connection between c ++ and c # direct images. However, this method will be stuck in the C # program. I have tried many methods of backgroundworker and task, but c # will get stuck. The specific reason is not clear, so I think the processing of this part is done using threads in c ++,
Notify c # After completion, because I need to generate four result images in a third-party DLL. So the struct is defined.
[C #]
[StructLayout (LayoutKind. Sequential)]
Public struct ImageResult
{
Public IntPtr First;
Public IntPtr Second;
Public IntPtr Third;
Public IntPtr Forth;
}
[C ++]
Struct ImgeResult
{
Void * FirstIMG;
Void * SecondIMG;
Void * ThirdIMG;
Void * FouthIMG;
};
Then define the delegate to the c ++ callback in C.
[C #]
Public delegate void CSCallback (ImageResult ir );
Public static CSCallback callback;
Callback = CSCallbackFunction;
SetCallback (callback );
Public static void CSCallbackFunction (ImageResult tick)
{
Process data returned by c ++
}
Call c ++ thread Functions
Public void Do (Bitmap bp)
{
Bitmap outIMG = new Bitmap (bp. Width, bp. Height );
System. drawing. imaging. bitmapData bmp data = bp. lockBits (new System. drawing. rectangle (0, 0, bp. width, bp. height), System. drawing. imaging. imageLockMode. readWrite,
Bp. PixelFormat );
DoImage (BMP data. Scan0, bp. Width, bp. Height, 3, 0, BMP data1.scan0 );
Img. UnlockBits (BMP data );
OutIMG. UnlockBits (BMP data1 );
}
[C ++]
Typedef void (_ stdcall * CPPCallback) (ImgeResult ir );
CPPCallback myCallback;
Extern "C" _ declspec (dllexport) void WINAPI SetCallback (CPPCallback callback)
{
MyCallback = callback;
}
Void OperateImage (unsigned char * img, int width, int height, int ch, int format)
{
Mat frame (Size (width, height), CV_8UC (ch), img );
Mat dest;
CvtColor (frame, dest, format = 0? CV_BGR2YUV_I420: CV_RGB2YUV_I420 );
Mat second;
CvtColor (frame, second, format = 0? CV_BGR2YUV_I420: CV_RGB2YUV_I420 );
Mat third;
CvtColor (frame, third, format = 0? CV_BGR2YUV_I420: CV_RGB2YUV_I420 );
Mat forth;
CvtColor (frame, forth, format = 0? CV_BGR2YUV_I420: CV_RGB2YUV_I420 );
Mat nextFirst;
Mat nextSecond;
Mat nextThird;
Mat nextTForth;
// Process images in a third-party library
CvtColor (dest, nextFirst, format = 0? CV_YUV2BGR_I420: CV_YUV2RGB_I420 );
CvtColor (second, nextSecond, format = 0? CV_YUV2BGR_I420: CV_YUV2RGB_I420 );
CvtColor (third, nextThird, format = 0? CV_YUV2BGR_I420: CV_YUV2RGB_I420 );
CvtColor (forth, nextTForth, format = 0? CV_YUV2BGR_I420: CV_YUV2RGB_I420 );
ReleaseBelleFaceEngine ();
Ir. FirstIMG = (void *) malloc (nextFirst. cols * nextFirst. rows * nextFirst. channels ());
Ir. SecondIMG = (void *) malloc (nextSecond. cols * nextSecond. rows * nextSecond. channels ());
Ir. ThirdIMG = (void *) malloc (nextThird. cols * nextThird. rows * nextThird. channels ());
Ir. FouthIMG = (void *) malloc (nextTForth. cols * nextTForth. rows * nextTForth. channels ());
Memcpy (ir. FirstIMG, (void *) nextFirst. data, nextFirst. cols * nextFirst. rows * nextFirst. channels ());
Memcpy (ir. SecondIMG, (void *) nextSecond. data, nextSecond. cols * nextSecond. rows * nextSecond. channels ());
Memcpy (ir. ThirdIMG, (void *) nextThird. data, nextThird. cols * nextThird. rows * nextThird. channels ());
Memcpy (ir. FouthIMG, (void *) nextTForth. data, nextTForth. cols * nextTForth. rows * nextTForth. channels ());
MyCallback (ir );
}
Extern "C" _ declspec (dllexport) void WINAPI DoImage (unsigned char * img, int width, int height, int ch, int format)
{
Std: thread th1 (OperateImage, img, width, height, ch, format );
Th1.detach ();
}
At this point, the c # program will not be stuck.
Because I used c ++ for the first time, I wrote it while checking it.
C ++ write experience.
(1) When using opencv, pay attention to whether the Link Library is debug or release.
(2) to install redist in a pure system, my target machine is 64-bit and the development environment is 2013. Therefore, vs2013redist must be installed.
(3) Pay attention to msvcp120.dll and msvcp120d. dll, msvcr120.dll, msvcr120d. dll, vccorlib120.dll, vccorlib120d. dll is placed in the C: \ Windows \ SysWOW64 directory, and 32-bit target machines are placed under win32.
If you have a better solution, please tell your younger brother.