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!
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!"
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?
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
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
Bitte benutze die richtigen Code-Tags [Hinweis] Wie poste ich richtig?
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!
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.
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
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).
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.
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).
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