【问题标题】:Unable to pass System.Drawing.Bitmap to C++ DLL无法将 System.Drawing.Bitmap 传递给 C++ DLL
【发布时间】:2017-09-11 09:44:00
【问题描述】:

我正在用 C++ 编写一个 DLL 来搜索位图中的子图片。 执行 C++ 部分时,HBITMAP 无效。

这是我的代码:

C#:

[System.Runtime.InteropServices.DllImport("FindSubPicture.dll", EntryPoint = "FindSubPictures", CallingConvention = CallingConvention.Cdecl)]
    private static extern System.IntPtr FindSubPicturesFct(System.IntPtr mImg, System.IntPtr sImg, int* nMatches);
    public static System.Collections.Generic.List<TPoint> FindSubPictures(System.Drawing.Bitmap mImg, System.Drawing.Bitmap sImg)
    {
        TPoint* PStack = null;
        int nMatches = 0;
        System.Collections.Generic.List<TPoint> MyList = new System.Collections.Generic.List<TPoint>();
        MyList.Clear();

        PStack = (TPoint*)FindSubPicturesFct(mImg.GetHbitmap(), sImg.GetHbitmap(), &nMatches);
        if(PStack == null) { return MyList;}

        for (int i = 0; i < nMatches; i++) { MyList.Add(new TPoint(PStack[i].x[0], PStack[i].x[1])); }
        try
        {
            System.Runtime.InteropServices.Marshal.FreeHGlobal((System.IntPtr)PStack);
        }catch(System.Exception ex) { System.Console.WriteLine(ex.Message); }

        return MyList;
    }

C++:

#include "FindSubPictures.h"
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <omp.h>

struct TPoint
{
    int x[2];

    TPoint(int fx, int fy) {
        x[0] = fx;
        x[1] = fy;
    }

    void Reset() { x[0] = 0; x[1] = 0; }
    void Set(int fx, int fy) { x[0] = fx; x[1] = fy; }
};

extern "C" __declspec(dllexport) TPoint* FindSubPictures(HBITMAP mImg, HBITMAP sImg, int* nMatches) {
    int mImgWidth = -1, mImgHeight = -1, sImgWidth = -1, sImgHeight = -1;
    TPoint* MyList = nullptr;

    if (mImg == nullptr || sImg == nullptr || nMatches == nullptr) { return nullptr; }


    return MyList;
}

嗯,C++ 库函数直到现在还没有做任何事情。那是因为HBITMAP 无效。在 C# 中,System.Drawing.Bitmap 是有效的。

当我输入“mIng.”时,没有自动完成功能。

我错过了什么吗?

【问题讨论】:

  • 参数列表中的匹配数在哪里?
  • 什么意思?
  • 我的错误。 c# 中的调用函数缺少不需要的匹配项。 : 公共静态 System.Collections.Generic.List FindSubPictures(System.Drawing.Bitmap mImg, System.Drawing.Bitmap sImg)

标签: c# c++ bitmap interop hbitmap


【解决方案1】:

获取位图并不意味着您可以像访问数据字段一样访问它。您必须先将位图数据锁定在内存中。 另请参阅此处this thread 中的答案。

Bitmap.LockBits

代码如下所示:

Rectangle rect = new Rectangle(0, 0, mImg.Width, mImg.Height);
System.Drawing.Imaging.BitmapData bmpData =
    mImg.LockBits(rect, System.Drawing.Imaging.ImageLockMode.Read,
    mImg.PixelFormat);

// Get the address of the first line.
IntPtr ptr2mImg = bmpData.Scan0;

【讨论】:

  • 嗯,我现在不太确定为什么GetHbitmap() 不起作用。但也许这会给你一个想法。喜欢就评论吧。
【解决方案2】:

好的,我有办法。

HBITMAP 只是一个句柄“void *”

你首先要通过函数GetObject得到完整的对象

代码:

extern "C" __declspec(dllexport) TPoint* FindSubPictures(HBITMAP mImg, HBITMAP sImg, int* nMatches) {
    int mImgWidth = -1, mImgHeight = -1, sImgWidth = -1, sImgHeight = -1;
    TPoint* MyList = nullptr;

    if (mImg== nullptr || sImg== nullptr || nMatches == nullptr) { return nullptr; }

    BITMAP mBMP, sBMP;
    GetObject(mImg, sizeof(BITMAP), &mBMP);
    GetObject(sImg, sizeof(BITMAP), &sBMP);
    /*Now, BITMAP mBMP and sBMP are valid*/

    return MyList;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    • 2013-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多