2012-01-14 83 views
3

我試圖沒有成功地在C#中編寫代碼以將位圖傳遞給非託管C++ DLL並返回POINT結構。將位圖從C#傳遞到C++非託管代碼

我在互聯網上做了大量的研究,但沒有找到「Gotcha」文章或一段代碼來幫助我解決我的問題。

迄今爲止我能夠想出的最好的方法是使用C#應用程序調用的託管C++ dll包裝的非託管C++ DLL。在測試中,我可以傳遞簡單的類型,例如整數並返回一個沒有問題的整數。現在我遇到的問題是位圖。我不能將參數1從'System :: IntPtr'轉換爲'HBITMAP'「和」不能將參數1從'System :: IntPtr'轉換爲編譯期間的錯誤, 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++知識是有限的。

+0

在'ImportWrap.cpp'中聲明的函數不正確。你不能將一個IntPtr(它傳遞給函數)隱式轉換爲一個'HBITMAP'類型(函數試圖傳遞給它調用的另一個函數)。 – 2012-01-14 12:25:02

回答

3

不能使用本機結構類型作爲返回值,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來使它更容易使用。

1

您完全可以跳過託管的C++包裝器,只需通過P/Invoke從C#中調用非託管DLL即可。把這樣的事情在你的C#類

[DllImport("YourUnamangedDll.dll")] 
private static extern POINT FindImage(IntPtr source, IntPtr target); 

我沒有測試過這一點,所以你可能需要調整它根據需要,但這是一般的想法。

相關問題