C#からC ++にbitmapを渡すことなく管理されていないコード
質問
C#でコードを作成して、マネージドされていないC ++ DLLにビットマップを渡し、ポイント構造を返すことに成功しなくても努力しています。
私はインターネットで多くの調査を行ってきましたが、私の問題を解決するのに役立つ「ゴッチャ」の記事やコードを見つけていません。
私がこれまでに思いつくことができた最高のものは、管理されたC ++ DLLで包まれた管理されていないC ++ DLLです。テストでは、整数などのシンプルなタイプを渡して、問題なく整数を返すことができます。今、私が抱えている問題について、ビットマップ。
hbitmapを渡してみました(c#でビットマップのgethbitmap()関数を使用して)が、「システム:: intptr」から「hbitmap」から「class1.findimage」に「パラメーター1を変換できません」のコンパイル中にエラーが発生します( 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#でロックビットを使用しても、十分に速くありません。そのため、画像検索には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へのアセンブリ参照を追加します。また、INTPTRの代わりにBitMap^を渡すことを検討して、さらに使いやすくすることもできます。
他のヒント
おそらく、管理されたC ++ラッパーを完全にスキップし、P/Invokeを介してC#から管理されていないDLLを呼び出すだけです。このようなものをC#クラスに入れてください
[DllImport("YourUnamangedDll.dll")]
private static extern POINT FindImage(IntPtr source, IntPtr target);
私はこれをテストしていないので、必要に応じて調整する必要があるかもしれませんが、それは一般的な考えです。