读书人

C#调用C++ dll的有关问题尝试读取或

发布时间: 2011-12-30 23:30:45 作者: rapoo

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的首地址搞出来,传进去。

读书人网 >C#

热点推荐