Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Wie kann man Bitmap in HBITMAP konvertieren?
doubleII
myCSharp.de - Member



Dabei seit:
Beiträge: 33

Themenstarter:

Wie kann man Bitmap in HBITMAP konvertieren?

beantworten | zitieren | melden

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!
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 6.779
Herkunft: Waidring

beantworten | zitieren | melden

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!"
private Nachricht | Beiträge des Benutzers
p!lle
myCSharp.de - Member

Avatar #avatar-3556.jpg


Dabei seit:
Beiträge: 1.040

beantworten | zitieren | melden

Hast du Google gefragt?

Bitmap.GetHbitmap
private Nachricht | Beiträge des Benutzers
doubleII
myCSharp.de - Member



Dabei seit:
Beiträge: 33

Themenstarter:

beantworten | zitieren | melden

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:
Fehler
"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?
private Nachricht | Beiträge des Benutzers
Spook
myCSharp.de - Member



Dabei seit:
Beiträge: 241
Herkunft: Esslingen a.N.

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
doubleII
myCSharp.de - Member



Dabei seit:
Beiträge: 33

Themenstarter:

beantworten | zitieren | melden

Hallo Spook,

habe auch versucht. Es zeigt mir folgender Fehler:
Fehler
System.Runtime.InteropServices.SEHException(0x80004005): Eine externe Komponente hat eine Ausnahme ausgelöst.

Grüße
doubleII

Moderationshinweis von Coffeebean (28.07.2016 - 13:16)

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

private Nachricht | Beiträge des Benutzers
doubleII
myCSharp.de - Member



Dabei seit:
Beiträge: 33

Themenstarter:

beantworten | zitieren | melden

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!
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4.176

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
doubleII
myCSharp.de - Member



Dabei seit:
Beiträge: 33

Themenstarter:

beantworten | zitieren | melden

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:
Fehler
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
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von doubleII am .
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4.176

beantworten | zitieren | melden

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).
private Nachricht | Beiträge des Benutzers
doubleII
myCSharp.de - Member



Dabei seit:
Beiträge: 33

Themenstarter:

beantworten | zitieren | melden

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.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von doubleII am .
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4.176

beantworten | zitieren | melden

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).
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Th69 am .
private Nachricht | Beiträge des Benutzers
doubleII
myCSharp.de - Member



Dabei seit:
Beiträge: 33

Themenstarter:

beantworten | zitieren | melden

Ich muss mal schauen, wie es gemacht wird.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von doubleII am .
private Nachricht | Beiträge des Benutzers
doubleII
myCSharp.de - Member



Dabei seit:
Beiträge: 33

Themenstarter:

beantworten | zitieren | melden

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:
Fehler
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
Dieser Beitrag wurde 4 mal editiert, zum letzten Mal von doubleII am .
private Nachricht | Beiträge des Benutzers