2012-01-14 32 views
3

アンマネージC++ DLLにビットマップを渡してPOINT構造体を返すために、C#でコードを書くことができません。ビットマップをC#からC++に渡すアンマネージドコード

私はインターネットで多くの研究を行ってきましたが、問題を解決するための記事やコードを見つけられませんでした。

私が今までに思い付くことができる最高のものは、管理されているC++ DLLでラップされた管理されていないC++ DLLです。これをテストする際には、整数などの単純な型を渡して問題のない整数を返すことができます。今私が持っている問題のために、ビットマップ。

私はHBitMAP(C#で私のビットマップのGetHBitmap()関数を使用しています)を渡そうとしましたが、コンパイル時に "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#でlockbitを使用していても、それは十分速くはありません。ですから、画像検索のためにC++コードを利用したいと思います。

私はさらに混乱に遭うと確信していますが、この障害を乗り越えることができれば、それを処理できるかもしれません。ご覧のとおり、私のC++の知識は限られています。

+0

'ImportWrap.cpp'で宣言された関数が正しくありません。 'IntPtr'(関数に渡される)を' HBITMAP'型(それが呼び出す他の関数に渡そうとする)に暗黙的に変換することはできません。 –

答えて

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へのアセンブリ参照を追加します。また、IntPtrの代わりにBitmap ^を渡して、さらに使いやすくすることを検討することもできます。

1

おそらくマネージC++ラッパーをスキップして、P/Invoke経由でC#からアンマネージDLLを呼び出すことができます。

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

あなたのC#クラスにこのようなものを入れて、私はこれをテストしていませんので、必要に応じて、あなたはそれを微調整する必要があるかもしれませんが、それは一般的な考えです。

関連する問題