안녕하세요...
C# 의 PictureBox 이미지를 C++ DLL 에서 바꾸는 문제 입니다. 
몇일째 찾아 보다가 도저히 답이 안나와서 문의 드리게 되었네요...
우선 개발 환경은 : 
OS : window8.1
Tool : Visual Studio 2012
Code 의 주석으로 설명할께요...
//----------------------------------------------------------------------
Main.C#    
//C++ DLL 호출
  [DllImport("CameraDll.dll")]
  static extern void dll_Button1_Click(IntPtr hwnd, int deviceIndex);
private void Button1_Click(object sender, EventArgs e)
{
  IntPtr inpt2 = pictureBox1.Handle;
  dll_Button1_Click( inpt2 , g_DeviceIndex);
}
//----------------------------------------------------------------------
CameraDll.CPP   DLL
unsigned char*        m_pDisplayBuffer;
unsigned char*      m_ppDisplayBuffer[2];
HWND hwnd;
////////////////////////////////////////////////////////////////////////////////////////////////
//    Display Image
////////////////////////////////////////////////////////////////////////////////////////////////
void DisplayImage(HDC hDC, int width, int height, int dw, int dh, unsigned char*pImage)
{
    HDC MemDC;
    BITMAPINFO        bmpInfo;
    BITMAPFILEHEADER bmFileHeader;
    BITMAP Bitmap;
    bmpInfo.bmiHeader.biSize            = sizeof(BITMAPINFOHEADER);
    bmpInfo.bmiHeader.biWidth           = width;
    bmpInfo.bmiHeader.biHeight          = height;
    bmpInfo.bmiHeader.biPlanes          = 1;
    bmpInfo.bmiHeader.biBitCount        = 24;
    bmpInfo.bmiHeader.biCompression     = BI_RGB ;
    bmpInfo.bmiHeader.biSizeImage       = 0;
    bmpInfo.bmiHeader.biXPelsPerMeter   = 0;
    bmpInfo.bmiHeader.biYPelsPerMeter   = 0;
    bmpInfo.bmiHeader.biClrUsed         = 0;
    bmpInfo.bmiHeader.biClrImportant    = 0;
    if(width == dw)
    {
        MemDC = CreateCompatibleDC(hDC);                                //<--- hdc : C#의  PictureBox HDC
        printf("Create BitMap\n");
    //    BitMapByteCallBackHandler(&h_bitmap);                          //<--  C#으로 이미지 Data를 가져와서 처리 하려고 시도...  
                                                                         // C#의 PictureBox 이미지를 변경 안됨!!!!!!!  실행시 오류 없이 진행 됨, Debug 오류 없음..
        SetDIBitsToDevice(MemDC,    0, 0,    (width), (height),    0, 0, 0, (height),    pImage,    &bmpInfo, DIB_RGB_COLORS); //<--- WinAPI에서 실행할 경우 변경됨
        DeleteDC(MemDC);
    }
    else
    {
        
    }
}
void MakeDisplayImage(int width, int height, unsigned char* pSrc, unsigned char* pDst)
{
    int wbytes;
    wbytes = width * 3;
    for(int i = 0; i < height; i++)
    {
        for(int j = 0; j < width; j++)
        {
            pDst[i * wbytes + j * 3]     = pSrc[((height - 1) - i) * width + ((width - 1) - j)];
            pDst[i * wbytes + j * 3 + 1] = pSrc[((height - 1) - i) * width + ((width - 1) - j)];
            pDst[i * wbytes + j * 3 + 2] = pSrc[((height - 1) - i) * width + ((width - 1) - j)];
        }
    }
}
void CALLBACK OnTimer(HWND fhwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
    int errorCode = 0;
    unsigned char*    pAddress;
    errorCode = UCamGetImageData(g_DeviceIndex, &pAddress);                                                           //<--- pAddress 를 통해 Display 할 이미지 Dataf가져옴
    if(errorCode == UCAM_NEW_FRAME)
    {
        SetWindowText(hwnd,"Test");                                                                               // <-- C# 의 Button Text 변경  X 안됨
        EnableWindow(hwnd, FALSE);                                                                                // <-- C# 의 Button Enable 변경 O 됨
        
                HDC hdc = GetDC(hwnd); 
        MakeDisplayImage(m_nWidth, m_nHeight, pAddress, m_ppDisplayBuffer[g_DisplayIndex]);                          // <---  ppDisplayBuffer
        DisplayImage(hdc, m_nWidth, m_nHeight, m_nDisplayWidth, m_nDisplayHeight, m_ppDisplayBuffer[g_DisplayIndex]);  <---- 이미지를 Display 호출 ****
        //m_PictureControl.ReleaseDC(hdc);
        g_DisplayIndex++;
        if(g_DisplayIndex == DISPLAY_BUFFERCOUNT)
        {
            g_DisplayIndex = 0;
        }
    }else{
        printf("-----------------------\n");
    }
}
extern "C" __declspec(dllexport) void __cdecl  dll_IDCUCAMSTART_Click(HWND fhwnd, int deviceIndex){  //<----- C#
    hwnd = fhwnd;
    
    BufferInitialize(); 
    USBReceiveCallback(USBReceiveHandler);
    SetTimer(NULL, ID_TIMER101, 500, OnTimer); 
    m_ReceiveMode = 1;
    UCamStart(g_DeviceIndex, m_ReceiveMode);
    m_bDisplayMode = false;
}
//----------------------------------------------------
DisplayImage 함수에서 CallBack 으로
C++ Dll
typedef void (__cdecl * BitMapByteCallback)(const HBITMAP fbyte);
HBITMAP OldBitmap;
HBITMAP hBitmap;
BITMAP bit;
int bx,by;
MemDC = CreateCompatibleDC(hDC);                    //<--- hdc : C#의  PictureBox HDC
hBitmap = CreateDIBitmap(MemDC,(BITMAPINFOHEADER *)&bmpInfo,CBM_INIT, (PBYTE)pImage,(BITMAPINFO *)&bmpInfo,DIB_RGB_COLORS);   
        
OldBitmap = (HBITMAP)SelectObject(MemDC, &hBitmap);      
BitMapByteCallBackHandler(OldBitmap);  <-- Callback C# Function 호출
C# CallBack
public void BitMapByteCallBackHandler(IntPtr hBitmap)
{
            
            Bitmap bitmap = null;
            try
            {
                bitmap = new Bitmap(Image.FromHbitmap(hBitmap));   // <-- System.Runtime.InteropServices.ExternalException (0x80004005): GDI+에서 일반 오류가 발생했습니다. 
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
}
왜 System.Runtime.InteropServices.ExternalException (0x80004005): GDI+에서 일반 오류가 발생했습니다. 발생할까요???
요약: 
1. C++ DLL 에서 C# 의 PictureBox의 이미지를 변경 하고 싶습니다.
2. BitMapByteCallBackHandler를 이용하여 C#으로 HBitMap 이미지를 보내서 
   C#에서 구현 하려고 한다면 어떻게 해야 할까요??
3. System.Runtime.InteropServices.ExternalException 
     
        
        
                    
                    
                    
                    
                    
    
                    
                    
                    
                    
                    
                
                    [최초 등록일: ]
                    [최종 수정일: 12/19/2013]