在托管代码中从非托管DLL加载位图文件

问题描述:

我正在尝试从非托管资源dll加载图像,并且在将从dll检索到的btye数组转换为位图图像时无法克服错误.

I'm trying to load a image from a unmanaged resource dll and have not been able to get past a error when converting the btye array retrieved from the dll to a bitmap image.

在Visual Studio中查看时,test.dll文件包含以下结构:
test.dll
位图
+411
图标
+1002 [英语(美国)

The test.dll file contains the following structure when viewed in visual studio:
test.dll
Bitmap
+411
Icon
+1002[English (United States]

当我双击ID 411(Bimap节点)时,我可以在位图编辑器中看到bmp文件. 当我双击ID 1002(图标节点)时,我可以在图标编辑器中看到不同的图标.

and when I double click the ID 411 (Bimap node) I can see the bmp file in the bitmap editor and when I double click the ID 1002 (Icon node) I can see the differnt icons in the icon editor.

所以我确定它们是有效的位图和图标,但是当我在下面运行测试时,它无法将字节数组转换为图像,因为它捕获到异常,显示参数无效Image.FromStream(...)错误".

So im certain that they are valid bitmap and icons, but when I run the test for below it cannot convert byte array to image as it catches the exception with "parameter is not valid Image.FromStream(..." error.

有人知道这是怎么回事.

Does anyone know what it wrong.

代码如下:

public partial class Form1 : Form
{
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr 
        LoadLibraryEx(string lpFileName, IntPtr hFile, int dwFlags);

    [DllImport("kernel32.dll")]
    static extern IntPtr FindResource(IntPtr hModule, int lpName, int lpType);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern uint SizeofResource(IntPtr hModule, IntPtr hResInfo);


    const int DATAFILE = 2;
    const int BITMAP_TYPE = 2;
    const int ICON_TYPE = 3;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void button1_Click(object sender, EventArgs e)
    {
        IntPtr loadLib = LoadLibraryEx("tsjcore.dll", IntPtr.Zero, DATAFILE);
        IntPtr findRes = FindResource(loadLib, 411, 2);
        IntPtr loadRes = LoadResource(loadLib, findRes);
        // Gives the correct size of image as
        uint size = SizeofResource(loadLib, findRes);  
        byte[] imageArray = new byte[size];
        // Loads the imageArray with data when viewed in debug mode.
        Marshal.Copy(loadRes, imageArray, 0, (int)size);
        Bitmap bitmap;
        try
        {
            using (MemoryStream memoryStream = new MemoryStream(imageArray))
            {
                bitmap = (Bitmap)Bitmap.FromStream(memoryStream);
            }
        }
        catch (Exception ex)
        {
            // displays parameter is not valid Image.FromStream(....
            MessageBox.Show(ex.ToString());
        }
    }
}

您将获得指向BITMAPINFOHEADER的指针,文件头丢失.因此Image.FromStream()无法正常工作.而是Pinvoke LoadBitmap()并使用Image.FromHbitmap().

You are getting a pointer to the BITMAPINFOHEADER, the file header is missing. So Image.FromStream() cannot work. Pinvoke LoadBitmap() instead and use Image.FromHbitmap().