Pregunta

Estoy intentando sin éxito escribir código en C# para pasar un mapa de bits a una DLL C ++ sin administrar y devolver una estructura de puntos.

He investigado mucho en Internet, pero no he encontrado el artículo o el código "Gotcha" para ayudarme a resolver mi problema.

Lo mejor que he podido encontrar hasta ahora es una DLL C ++ sin administrar, envuelta con una DLL C ++ administrada, llamada por mi aplicación C#. Al probar eso, puedo pasar tipos simples, como un entero y devolver un entero sin ningún problema. Ahora por el problema que estoy teniendo, el mapa de bits.

He intentado pasar una función HBITMAP (usando la función GetHBitMap () de mi mapa de bits en C#), pero recibo errores durante la compilación de "No se puede convertir el parámetro 1 de 'System :: intptr' a 'HbitMap'" y "class1.FindImage ( nulo *, nulo *) es inaccesible debido a su nivel de protección ".

Aquí está algunos de mi código:

Aplicación principal:

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);
}

Imgfunc.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);
    };
}

Imgfunc.cpp

namespace ImgFuncs
{
POINT MyImgFuncs::FindImage(HBITMAP source, HBITMAP target)
{
    POINT p;

    p.x = 1;
    p.y = 2;
    return p;
}
}

¿Qué estoy haciendo mal, o me voy completamente fuera del mapa con mi enfoque? Con mucho gusto entretendría cualquier sugerencia sobre la forma correcta de codificar lo que estoy tratando de hacer. Tengo un código C ++ que se usa para encontrar una imagen dentro de otra imagen que funcione bastante rápido. Desafortunadamente, incluso usando bloqueos en C#, no es lo suficientemente rápido. Por lo tanto, me gustaría usar el código C ++ para la búsqueda de imágenes.

Estoy seguro de que me encontraré con más enganches, pero podría manejarlo si puedo superar este obstáculo. Como puede ver, mi conocimiento de C ++ es limitado.

¿Fue útil?

Solución

No puede usar tipos de estructura nativos como valor de retorno, C# no puede manejarlos. El lanzamiento de IntPTR a HBITMAP requiere un reparto doble. Como esto:

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);
}

Agregue una referencia de ensamblaje al sistema. Es posible que también desee considerar pasar un mapa de bits^ en lugar de un intptr para que sea aún más fácil de usar.

Otros consejos

Probablemente podría omitir el envoltorio C ++ administrado por completo y simplemente llamar al DLL no administrado desde C# a través de P/Invoke. Pon algo como esto en tu clase C#

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

No he probado esto, por lo que es posible que deba ajustarlo según sea necesario, pero esa es la idea general.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top