我试图在 C# 中编写代码以将位图传递给非托管 C++ DLL 并返回一个 POINT 结构,但没有成功。
我在互联网上做了很多研究,但没有找到“Gotcha”文章或一段代码来帮助我解决我的问题。
到目前为止,我能想出的最好的是一个非托管的 c++ DLL,用托管的 c++ dll 包装,由我的 C# 应用程序调用。在测试时,我可以传递简单的类型,例如整数并返回一个整数,没有问题。现在对于我遇到的问题,位图。
我曾尝试传递一个 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);
}
}
导入包装.h:
namespace ImportWrap {
public ref class Class1
{
public:
static POINT FindImage(IntPtr source, IntPtr target);
};
}
导入包装.cpp:
static POINT FindImage(IntPtr source, IntPtr target)
{
return ImgFuncs::MyImgFuncs::FindImage(source, target);
}
函数文件
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;
}
}
我做错了什么,还是我的方法完全脱离了 map ?
我很乐意接受有关正确编码我正在尝试做的事情的任何建议。
我有一些 C++ 代码,用于在另一个运行速度非常快的图像中查找图像。不幸的是,即使在 c# 中使用锁位,它也不够快。所以我想利用c++代码进行图像搜索。
我相信我会遇到更多的障碍,但如果我能克服这个绊脚石,我可能能够处理它。如您所见,我的 C++ 知识有限。
最佳答案
您不能使用 native 结构类型作为返回值,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# - 将位图从 C# 传递到 C++ 非托管代码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8861029/