Laden...

Wie kann man Bitmap in HBITMAP konvertieren?

Erstellt von doubleII vor 7 Jahren Letzter Beitrag vor 7 Jahren 4.079 Views
D
doubleII Themenstarter:in
33 Beiträge seit 2016
vor 7 Jahren
Wie kann man Bitmap in HBITMAP konvertieren?

Hallo, ich habe eine Frage und zwar, wie konvertiert man ein Bitmap format in einem HBITMAP um den Wert in einer Unmanaged Funktion zu übergeben?



 [DllImport("Toolbox.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
static extern int Execute(uint Count, HBITMAP Bitmaps);



 private void btnExecute_Click(object sender, EventArgs e)
        {
            uint Count = 1; // counter heißt 1 Kameras 
            HBITMAP Bitmaps = _bitmap; // in private Bitmap _bitmap wird das Image als Bitmap format gespeichert

            try
            {
      
                //???????????????????????
                int execute = Execute(Count, Bitmaps);
                listBox1.Items.Add("I'm Execute: " + execute);

            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

Vielen Dank!

6.911 Beiträge seit 2009
vor 7 Jahren

Hallo doubleII,

Bitmap.GetHbitmap Method (System.Drawing) hilft dir nicht?

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

1.040 Beiträge seit 2007
vor 7 Jahren

Hast du Google gefragt? 😉

Bitmap.GetHbitmap

D
doubleII Themenstarter:in
33 Beiträge seit 2016
vor 7 Jahren

ja stimmt, dumme Frage aber ich habe auch so mit der Methode versucht. Das Problem war wo anders. Jetzt passt. Danke 😃.

Es zeigt mir ein andere Fehler:

FEHLER:> Fehlermeldung:

"Es wurde versucht, im geschützten Speicher zu lesen oder zu schreiben. Dies ist häufig ein Hinweis darauf, dass anderer Speicher beschädigt ist."

Nach Ihre Meinung ist die Funktion richtig in C# richtig deklariert?

in C++

int Execute(unsigned int count, HBITMAP* bmp);


using HBITMAP = System.IntPtr;


[DllImport("Toolbox.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl, EntryPoint = "Execute")]
static extern int Execute(uint count, HBITMAP bmp);

Durch Google habe ich noch herausgefunden, dass es womöglich an der Aufrufkonvention stdcall liegt. Hat jemand eine Idee, woran kann es liegen?

S
248 Beiträge seit 2008
vor 7 Jahren

Hallo doubleII,

wenn in der C++ Funktion der Parameter vom Typ HBITMAP* definiert ist, dann definiere den Parameter in C# mit ref:

[DllImport("Toolbox.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl, EntryPoint = "Execute")]
static extern int Execute(uint count, ref HBITMAP bmp);

Grüße
spooky

D
doubleII Themenstarter:in
33 Beiträge seit 2016
vor 7 Jahren

Hallo Spook,

habe auch versucht. Es zeigt mir folgender Fehler:> Fehlermeldung:

System.Runtime.InteropServices.SEHException(0x80004005): Eine externe Komponente hat eine Ausnahme ausgelöst.

Grüße
doubleII

Hinweis von Coffeebean vor 7 Jahren

Bitte benutze die richtigen Code-Tags [Hinweis] Wie poste ich richtig?

D
doubleII Themenstarter:in
33 Beiträge seit 2016
vor 7 Jahren

Hallo zusammen,

wenn ich nur ein Bild übergeben möchte

HBITMAP bitmaps = _bmp.GetHbitmap Method ();

funktioniert reibungslos. Jetzt habe ich mehr als eine Kamera (Beispiel zwei Kameras) und die Bilder von der beiden Kamera habe ich als


private Bitmap _bm1;
private Bitmap _bm2;

gespeichert. Ich muss sie jetzt an HBITMAP bitmaps übergebe. Hat jemand eine Idee wie ich es machen könnte. In diesem Fall ist der counter auf zwei -> Anzahl der Kameras.
😦

Vielen vielen Dank!

4.931 Beiträge seit 2008
vor 7 Jahren

Probiere mal


IntPtr[] bitmaps = new IntPtr[2];
bitmaps[0] = _bm1.GetHbitmap();
bitmaps[1] = _bm2.GetHbitmap();

int execute = Execute(bitmap.Length, bitmaps);

Evtl. mußt du dann noch die Signatur der 'Execute'-Methode anpassen.

D
doubleII Themenstarter:in
33 Beiträge seit 2016
vor 7 Jahren

Hallo Th69,

wunderbar, vielen Dank für die Hilfe. Es funktioniert, aber wenn ich die Applikation von Debugging mode aufrufe es zeigt mir folgende Fehlermeldung:> Fehlermeldung:

Ausnahme ausgelöst bei 0x00000000(Toolbox.dll) in App.exe: 0xC0000005: Zugangsverletzung beim Lesen an Position 0x00000000.

Falls ein Handle für diese Ausnahme vorhanden ist, kann das Programm möglicherweise sicher ausgeführt werden.

Ich habe den Code so umgeschrieben:



 [DllImport("Toolbox.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, EntryPoint = "Execute")]
static extern in Execute(int count, HBITMAP[] bitmaps);

 private void btnExecute_Click(object sender, EventArgs e)
        {
            int count = 0;
            
            HBITMAP[] bitmaps = new HBITMAP[2];
          
            bitmaps[0] = bm[0].GetHbitmap();  // private Bitmap [] bm = new Bitmap[2]; 
            bitmaps[1] = bm[1].GetHbitmap();
          
            count = bitmaps.Length;


            try
            {
                
                int execute = Execute(count,  bitmaps);
                listBox1.Items.Add("I'm Execute: " + execute);            
            }

            catch (Exception ex)
            {
               
                MessageBox.Show(ex.ToString());
            }

        }



weißt du vielleicht woran kann es liegen? Der Fehler wird gezeigt, wenn

int execute = Execute(counter, bitmaps);

ausgefühlt wird. Zeigerproblem habe gesucht aber finde keine Lösung.

Schöne Grüße
doubleII

4.931 Beiträge seit 2008
vor 7 Jahren

Tja, dann ist wohl doch noch etwas falsch deklariert.
Mir fällt noch das MarshalAs-Attribut ein: Gewusst wie: Marshallen von Arrays mit PInvoke


static extern in Execute(int count, [MarshalAs(UnmanagedType::LPArray)]HBITMAP[] bitmaps);

Überprüfe aber auch mal den Array-Inhalt (von 'bitmaps'), d.h. ob wirklich sinnvolle Werte da drin stehen (die Fehlermeldung deutet auf einen Nullwert hin).

D
doubleII Themenstarter:in
33 Beiträge seit 2016
vor 7 Jahren

Hallo Th69,

es hängt irgendwie. Ich lade die Bilder aber wenn ich sie auswerten möchte stürzt alles ab, es hat sich nichts geändert. Verstehe nicht.

  
[DllImport("Toolbox.dll", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl, EntryPoint = "Execute")]static extern int Execute(int count, [MarshalAs(UnmanagedType.LPArray)] HBITMAP[] bitmaps);

Beim Debugging unter Lokal
bekomme ich für bitmaps Bsp so was:

bitmaps
-> [0] {-184216928}
-> [1] {386207774}

aber ich bekomme keinen null Wert.

4.931 Beiträge seit 2008
vor 7 Jahren

Wenn du auf diesem Wege nicht weiterkommst, dann würde ich dir empfehlen, mal ein C++/CLI Projekt aufzusetzen um die native Funktion direkt aufzurufen.
Und vom C#-Projekt greifst du dann auf dieses C++/CLI-Projekt zu (so hast du dann bessere Debugmöglichkeiten bzgl. der Übergabe deiner Parameter).

PS: Die Handles sehen gut aus (entsprechen Adressen, d.h. sollten durch 4 teilbare Zahlen sein).

D
doubleII Themenstarter:in
33 Beiträge seit 2016
vor 7 Jahren

Ich muss mal schauen, wie es gemacht wird.

D
doubleII Themenstarter:in
33 Beiträge seit 2016
vor 7 Jahren

Hallo Th69,

komischerweise habe den Code so umgeändert und es funktioniert.


[DllImport("E:\\Laser 2000\\Debug\\ScorpionVisionToolbox.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, EntryPoint = "Execute")]
        static extern int Execute(int count, ref HBITMAP[] bitmaps); //nur ref HBITMAP [ ]
// Die Funktion hat einen Ausgabetype HRESULT 
// Den habe ich mit int ersetzt aber man kann auch mit 
//HRESULT = System.IntPtr; es funktioniert
 private void btnExecute_Click(object sender, EventArgs e)
        {
            int count = 0;
            HBITMAP[] bitmaps = new HBITMAP[3];
            bitmaps[0] = bm[0].GetHbitmap();
            bitmaps[1] = bm[1].GetHbitmap();
            bitmaps[2] = bm[2].GetHbitmap();
            count = bitmaps.Length;


            try
            {                
                    //LoadConfig(fname);
                    int hresult = Execute(count, ref bitmaps);
                    listBox1.Items.Add("I'm Execute: " + hresult);                           
            }

            catch (NullReferenceException ex)
            {
                MessageBox.Show(ex.ToString());
            }

            catch (DllNotFoundException ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

Be der Funktion habe ich wieder das gleiche Problem und die Funktion ist ziemlich einfach.



        [DllImport("Toolbox.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        static extern int GetString([MarshalAs(UnmanagedType.LPStr)] string tag, [MarshalAs(UnmanagedType.LPStr)]string value, uint valueSize, bool valid);

 private void btnGetString_Click(object sender, EventArgs e)
        {
            bool valid = true;
            uint valueSize = 1024;
            string tag =" ";
            string value = " ";
       
            //String ausgeben 
            tag = textBox2.Text;    // wird ein String gespeichert 
            listBox1.Items.Add("I'm Tag von Getstring:" +tag);
                                 
            try
            {
                if(String.IsNullOrEmpty(tag))
                {
                    listBox1.Items.Add("Tag ist null");
                }
                int getString = GetString(tag, value, valueSize, valid); // hier tritt die Fehlermeldung ein
                listBox1.Items.Add("I'm GetString: " + getString);
                // send 0 for succeed, or error code
  
                textBox3.Text = value.ToString(); // der Wert, der zurückgeliefert werden soll
                if (value != null)
                {
                    checkBoxValid.Checked = true;
                }

            }

            catch (NullReferenceException ex)
            {
                MessageBox.Show(ex.ToString());
            }
            
        }



ich übergebe ihr einen Parameter (tag), wenn der Wert stimmt dann wird von der Toolbox ein Wert (velue) ausgelesen. Wenn ich die Funktion aufrufe und unkorrekten tag eingebe zeigt mir, dass der Parameter falsch ist, wenn ich der richtige schreibe zeigt mir wieder 0x00000000, obwohl eine NullReferenceExeption vorgesehen habe. Es zeigt mir unter
Auto -> this -> AccessibilityObject
folgende Fehlermeldung:> Fehlermeldung:

Der Ausdruck kann nicht evaluirt werden, da sich ein nativer Frame oben auf dem Stack befindet.

Ich habe für das Problem etwas gefunden aber es hilft mir irgendwie nicht.
http://stackoverflow.com/questions/10851719/cannot-evaluate-expression-because-a-native-frame-is-on-top-of-the-call-stack
Weiß du zufällig wie vermeidet man Stacküberlauf? Wie geht man mit diesem Problem um, bsp. hier?
Wäre super, wenn jemand darüber etwas reinschreibt.
Ich habe nicht geschrieben aber es ist eine Software 32 Bit.

Schöne Grüße
doubleII