[英]Passing Bitmap from C# to C++ Unmanaged code
我試圖在C#中編寫代碼以將位圖傳遞給非托管c ++ DLL並返回POINT結構,但沒有成功。
我在互聯網上做了很多研究,但沒有找到“Gotcha”文章或一段代碼來幫助我解決我的問題。
到目前為止,我能夠提出的最好的是一個非托管的c ++ DLL,包含一個托管的c ++ dll,由我的C#app調用。 在測試中,我可以傳遞簡單類型,例如整數,並返回一個沒有問題的整數。 現在我遇到的問題是位圖。
我試過傳遞HBITMAP(在c#中使用我的位圖的GetHBitmap()函數)但是在編譯“無法將參數1從'System :: IntPtr'轉換為'HBITMAP'”和“Class1.FindImage”時出錯void *,void *)由於其保護級別而無法訪問“。
這是我的一些代碼:
主要應用:
class Program
{
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public POINT(int x, int y)
{
this.X = x;
this.Y = y;
}
public static implicit operator System.Drawing.Point(POINT p)
{
return new System.Drawing.Point(p.X, p.Y);
}
public static implicit operator POINT(System.Drawing.Point p)
{
return new POINT(p.X, p.Y);
}
}
static void Main(string[] args)
{
Image src = Image.FromFile("Pin.png");
Image tgt = Image.FromFile("screen.png");
Bitmap bsrc = new Bitmap(src);
Bitmap btgt = new Bitmap(tgt);
IntPtr bs = bsrc.GetHbitmap();
IntPtr bt = btgt.GetHbitmap();
POINT p = Class1.FindImage(bs, bt);
}
}
ImportWrap.h:
namespace ImportWrap {
public ref class Class1
{
public:
static POINT FindImage(IntPtr source, IntPtr target);
};
}
ImportWrap.cpp:
static POINT FindImage(IntPtr source, IntPtr target)
{
return ImgFuncs::MyImgFuncs::FindImage(source, target);
}
ImgFuncs.h
typedef long LONG;
typedef void *PVOID;
typedef PVOID HANDLE;
typedef HANDLE HBITMAP;
typedef struct tagPOINT {
LONG x;
LONG y;
} POINT, *PPOINT;
namespace ImgFuncs
{
class MyImgFuncs
{
public:
static __declspec(dllexport) POINT FindImage(HBITMAP source, HBITMAP target);
};
}
ImgFuncs.cpp
namespace ImgFuncs
{
POINT MyImgFuncs::FindImage(HBITMAP source, HBITMAP target)
{
POINT p;
p.x = 1;
p.y = 2;
return p;
}
}
我做錯了什么,或者我用我的方法完全脫離地圖? 我會很樂意接受有關正確編碼我想要做的事情的正確方法的任何建議。 我有一些C ++代碼用於在另一個圖像中查找工作得非常快的圖像。 不幸的是,即使在c#中使用lockbits,也不夠快。 所以我想利用c ++代碼進行圖像搜索。
我相信我會遇到進一步的障礙,但如果我能夠通過這個絆腳石,我或許可以處理它。 如您所見,我的C ++知識是有限的。
您不能使用本機結構類型作為返回值,C#無法處理它們。 從IntPtr到HBITMAP的轉換需要雙重演員。 像這樣:
static System::Drawing::Point FindImage(IntPtr source, IntPtr target)
{
POINT retval = ImgFuncs::MyImgFuncs::FindImage((HBITMAP)(void*)source, (HBITMAP)(void*)target);
return System::Drawing::Point(retval.X, retval.Y);
}
向System.Drawing添加程序集引用。 您可能還想考慮傳遞Bitmap ^而不是IntPtr,以使其更易於使用。
您可以完全跳過托管C ++包裝器,只需通過P / Invoke從C#調用非托管DLL。 把這樣的東西放在你的C#類中
[DllImport("YourUnamangedDll.dll")]
private static extern POINT FindImage(IntPtr source, IntPtr target);
我沒有對此進行測試,因此您可能需要根據需要進行調整,但這是一般的想法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.