首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

C#调用C++ dll的有关问题,尝试读取或写入受保护的内存,这通常指示其他内存已损坏

2011-12-30 
C#调用C++ dll的问题,尝试读取或写入受保护的内存,这通常指示其他内存已损坏用C++封装的DLL,其中函数用到

C#调用C++ dll的问题,尝试读取或写入受保护的内存,这通常指示其他内存已损坏
用C++封装的DLL,其中函数用到结构,C++中的函数如下:
extern   "C "     bool   __stdcall   SaveBMPFile(LPCSTR   lpFileName,   BITMAPINFO*   pBmpInfo,   BYTE   *pImageBuffer)
  {
  BOOL   bRVal=   FALSE;
  DWORD   dwBytesRead=   0;
  DWORD   dwSize=   0;
  BITMAPFILEHEADER   bfh=   {0};
  int   nTable=   0;
  DWORD   dwImageSize=   0;
 
  if   (pBmpInfo-> bmiHeader.biBitCount   >   8)   {
  nTable   =   0;
  }
  else{
  nTable   =   256;
  }
 
  dwImageSize   =(((pBmpInfo-> bmiHeader.biWidth   *   pBmpInfo-> bmiHeader.biBitCount)   +   31)   /   32   *   4   )*   pBmpInfo-> bmiHeader.biHeight;
 
  if   (dwImageSize   <=   0)   {
  bRVal   =   FALSE;
  MessageBox(NULL, "dwImageSize   <=   0 ",NULL,MB_OK);
  }
  else{
  bfh.bfType=   (WORD) 'M '   < <   8   |   'B ';
  bfh.bfOffBits=   sizeof(BITMAPFILEHEADER)   +   sizeof(BITMAPINFOHEADER)   +   nTable   *   sizeof(RGBQUAD);
  bfh.bfSize=   bfh.bfOffBits   +   dwImageSize;
 
  HANDLE   hFile   =   ::CreateFile(lpFileName,
  GENERIC_WRITE   ,
  0,
  NULL,
  CREATE_ALWAYS,
  FILE_ATTRIBUTE_NORMAL,
  NULL
  );
  if   (hFile   ==   INVALID_HANDLE_VALUE)   {
  bRVal   =   FALSE;
  MessageBox(NULL, "hFile=   0 ",NULL,MB_OK);
 
  }
  else{
  dwSize   =   sizeof(BITMAPFILEHEADER);
  ::WriteFile(hFile,   &bfh,   dwSize,   &dwBytesRead,   NULL   );
 
  dwSize   =   sizeof(BITMAPINFOHEADER)   +   nTable   *   sizeof(RGBQUAD);
  ::WriteFile(hFile,   pBmpInfo,   dwSize,   &dwBytesRead,   NULL   );
 
  dwSize   =   dwImageSize;
  WriteFile(hFile,   pImageBuffer,   dwSize,   &dwBytesRead,   NULL   );
 
  CloseHandle(hFile);
  MessageBox(NULL, "Writefile=   0 ",NULL,MB_OK);
 
 
  }
  }
 
  return   bRVal;
}
----------------------------------
C#中声明的相关结构:
[StructLayout(LayoutKind.Sequential)]    
                public   struct     BITMAPFILEHEADER
                {
                        public   ushort   bfType;
                        public   int   bfSize;
                        public   ushort   bfReserved1;
                        public   ushort   bfReserved2;
                        public   uint   bfOffBits;


                }

                [StructLayout(LayoutKind.Sequential)]  
                public   struct   BITMAPINFOHEADER
                {
                        public   uint   biSize;
                        public   int   biWidth;
                        public   int   biHeight;
                        public   ushort   biPlanes;
                        public   ushort   biBitCount;
                        public   uint   biCompression;
                        public   int   biSizeImage;
                        public   int   biXPelsPerMeter;
                        public   int   biYPelsPerMeter;
                        public   uint   biClrUsed;
                        public   uint   biClrImportant;

                }

                [StructLayout(LayoutKind.Sequential)]
                public   struct   RGBQUAD
                {
                        public   byte   Red;
                        public   byte   Green;
                        public   byte   Blue;
                        public   byte   reserved;
                }

               
                [StructLayout(LayoutKind.Sequential)]    
                public   struct   BITMAPINFO
                {
                        public   BITMAPINFOHEADER   header;
                        [MarshalAs(UnmanagedType.ByValArray,SizeConst=1)]
                        public   RGBQUAD[]   bmiColors;
                }
---------------
C#中调用DLL:
[DllImport( "mydll.dll ",   EntryPoint   =   "SaveBMPFile ",CharSet   =   CharSet.Ansi)]              
                public   static   extern   bool   SaveBMPFile(   string   filepath,   ref   BITMAPINFO   bmpinfo,   ref   byte   pImageBuffer);



----------------------------------------------------
C#中调用函数如下:
bool   rsult   =   DH_CGCard.SaveBMPFile( "E:\\Test "   +   i.ToString()   +   ".bmp ",   ref   bminfo,   ref   pBuffer[0]);                  

-----------------------------
不能成功,提示尝试读取或写入受保护的内存,这通常指示其他内存已损坏,
--------------------------------------------------
问题:如何才能调用我的dll中的函数,C#中如何声明,拜托高手,定给高分,在线等!

[解决办法]
首先,请确定你传入的参数在c#中都new过了。然后,试试以下的做法。
定义一个buffer
struct Buffer
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=自己指定)]
public byte[] pBuffer;
}

然后,SaveBMPFile的第三个参数改成IntPtr类型的:
在使用之前,new一个Buffer,用System.Runtime.InteropServices.Marshal.StructureToPtr将new出来的Buffer的首地址搞出来,传进去。

热点排行