Hilfe bei Easylase.dll und C#

Allgemeine Fragen zu Lasershow Software und Show-Programmierung.
Antworten
Benutzeravatar
jokakilla
Beiträge: 36
Registriert: Do 07 Aug, 2003 5:05 pm
Wohnort: Braunschweig
Kontaktdaten:

Hilfe bei Easylase.dll und C#

Beitrag von jokakilla » Do 06 Mär, 2008 9:18 am

Moin moin,
ich hab nach längerer Zeit mal wieder meine Anlage angeschmissen und mir natürlich den aktuellen Treiber für die Easylase runtergeladen. Habe dann gleich mal Lasertennis und Astroids ausprobiert und war schon ziemlich begeistert :)
Kurzum inspiriert davon wollte ich mich mal dran machen und was eigenes, bevorzugt in C#, programmieren. Ich stehe noch ganz am Anfang und komme leider nicht so recht weiter.
In der Dokumentation der DLL ist die Funktion zum Schreiben eines Frames wie folgt definiert:

Code: Alles auswählen

Function EasyLaseWriteFrame(CardNumber:integer, Datapointer:pointer,
Byteanzahl:integer, Punktspeed :word):boolean
Mein C# Code bisher:

Code: Alles auswählen

    public partial class Form1 : Form
    {
        [DllImport("easylase.dll")]
        public static extern int EasyLaseGetCardNum();
        [DllImport("easylase.dll")]
        public static unsafe extern bool EasyLaseWriteFrame(int cardNumber, byte[] datapointer, int bytecount, int speed);
        [DllImport("easylase.dll")]
        public static extern bool EasyLaseStop(int cardNumber);
        [DllImport("easylase.dll")]
        public static extern bool EasyLaseClose();

        private int easylaseCount;

        public unsafe Form1()
        {
            InitializeComponent();
            easylaseCount = EasyLaseGetCardNum();

            if (easylaseCount > 0)
            {
                byte[] frame = new byte[] { 0, 0, 0, 0, 255, 0, 0, 255, 128, 0, 0, 0, 255, 0, 0, 255 };
                EasyLaseWriteFrame(0, frame, 16, 5000);
            }
            
        }

        private void Form_Closing(object sender, EventArgs e)
        {
            if (easylaseCount > 0)
            {
                EasyLaseStop(0);
                EasyLaseClose();
            }
        }
    }

Das Funktioniert nicht :( Gibt mecker zur Laufzeit.
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.
Ich hab es auch schon mit diversen Varianten versucht z.B.

Code: Alles auswählen

  
        [DllImport("easylase.dll")]
        public static unsafe extern bool EasyLaseWriteFrame(int cardNumber, byte *[]datapointer, int bytecount, int speed);
              byte []frame = new byte[] { 0, 0, 0, 0, 255, 0, 0, 255, 128, 0, 0, 0, 255, 0, 0, 255 };
                fixed(byte *ptr = frame);
                EasyLaseWriteFrame(0, ptr, 16, 5000);
Da nörgelt der Compiler schon beim fixed(...) Warning möglicherweise falsche leere Anweisung.
EasyLaseWriteFrame(...) Error Der Name ptr ist im aktuellen Kontext nicht vorhanden.


Kann mir vielleicht jemand auf die Sprünge helfen? Eigentlich wäre ein zweidimensionales Array später doch auch einfacher zu handhaben oder? n*8 Byte. Wie macht man sowas mit Pointern in C#?

Ohne ist ja nicht schwer:

Code: Alles auswählen

byte[,] 3x3array = byte[,] {{0,1,2}, {0,1,2}, {1,2,3}};

Benutzeravatar
jojo
Beiträge: 1939
Registriert: Fr 21 Dez, 2001 12:00 pm
Do you already have Laser-Equipment?: -
Wohnort: Germany
Kontaktdaten:

Beitrag von jojo » Do 06 Mär, 2008 9:54 am

Sind die Beispiele fĂĽr C++ nicht als Anhaltspunkt zu verwenden?

Bei Dir kommt nirgends die Call convention "__stdcall" vor.
Ich glaube aber, das ist wichtig, damit die Ăśbergaben auf dem Stack passen.

Code: Alles auswählen

[DllImport("easylase.dll", CallingConvention = CallingConvention.StdCall)] 
oder so in etwa?

Joachim

Benutzeravatar
jokakilla
Beiträge: 36
Registriert: Do 07 Aug, 2003 5:05 pm
Wohnort: Braunschweig
Kontaktdaten:

Beitrag von jokakilla » Do 06 Mär, 2008 10:12 am

Hat leider nicht geholfen :(

Code: Alles auswählen

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace LaserTTT
{
    public partial class Form1 : Form
    {
        [DllImport("easylase.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern int EasyLaseGetCardNum();
        [DllImport("easylase.dll", CallingConvention = CallingConvention.StdCall)]
        public static unsafe extern bool EasyLaseWriteFrame(int cardNumber, byte *datapointer, int bytecount, int speed);
        [DllImport("easylase.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern bool EasyLaseStop(int cardNumber);
        [DllImport("easylase.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern bool EasyLaseClose();

        private int easylaseCount;

        public unsafe Form1()
        {
            InitializeComponent();
            easylaseCount = EasyLaseGetCardNum();

            if (easylaseCount > 0)
            {
                byte []frame = new byte[] { 0, 0, 0, 0, 255, 0, 0, 255, 128, 0, 0, 0, 255, 0, 0, 255 };
                fixed (byte *array = frame)
                {
                    EasyLaseWriteFrame(0, array, 16, 5000);
                
                }
                
            }
            
        }

        private void Form_Closing(object sender, EventArgs e)
        {
            if (easylaseCount > 0)
            {
                EasyLaseStop(0);
                EasyLaseClose();
            }
        }
    }
}
Gibt auch nen 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.

Benutzeravatar
afrob
Beiträge: 995
Registriert: Mo 05 Aug, 2002 12:00 pm
Do you already have Laser-Equipment?: RayComposer NET und RayComposer USB
Wohnort: Frankfurt am Main, Germany
Kontaktdaten:

Beitrag von afrob » Do 06 Mär, 2008 1:01 pm

[DllImport("easylase.dll", CallingConvention = CallingConvention.StdCall)]
public static unsafe extern bool EasyLaseWriteFrame(int *cardNumber, byte *datapointer, int bytecount, int speed);
[DllImport("easylase.dll", CallingConvention = CallingConvention.StdCall)]
public static extern bool EasyLaseStop(int *cardNumber);

wäre einen Versuch wert.

GrĂĽsse,
afrob

Benutzeravatar
jojo
Beiträge: 1939
Registriert: Fr 21 Dez, 2001 12:00 pm
Do you already have Laser-Equipment?: -
Wohnort: Germany
Kontaktdaten:

Beitrag von jojo » Do 06 Mär, 2008 4:39 pm

Hinweis:

"Speed" ist kein Integer.
Ein Integer hat (zumindest auf dem PC) 32Bit.
Speed ist aber ein 16 Bit-WORD (aus Delphi), also "unsigned short"!

Joachim

Benutzeravatar
thomasf
Beiträge: 1261
Registriert: So 06 Okt, 2002 12:00 pm
Do you already have Laser-Equipment?: YES
Wohnort: Berlin
Kontaktdaten:

Beitrag von thomasf » Do 06 Mär, 2008 5:23 pm

Hi,

also ich kenne mich ĂĽberhaupt nicht mit C# aus diese ganze .net geschichte nervt sowieso aber okay.

ich glaube der fehler liegt darin das du dein Frame array nicht vordeviniert hast. es muĂź [0..128000] byte groĂź sein und nicht dynamisch.

gruĂź thomas

Benutzeravatar
jokakilla
Beiträge: 36
Registriert: Do 07 Aug, 2003 5:05 pm
Wohnort: Braunschweig
Kontaktdaten:

Beitrag von jokakilla » Do 06 Mär, 2008 6:05 pm

Vielen Dank schonmal fĂĽr eure Ideen.

Leider bleibt der Fehler bestehen :(
Hatte zwischenzeitlich die Cardnumber als Pointer deklariert wobei mir der Sinn auch nicht ganz klar ist.
Ops der Speed ist jetzt ein unsigned short (ushort). Thx.

Ich dachte eigentlich man müsse nur die Punkte definiere, die man auch setzen möchte. Das 128k Array bringt leider auch nichts. Habs schon extra nochmal mit nullen gefüllt obwohl das ja eigentlich auch uninitialisiert so sein sollte.
Typen Casten bei den Konstanten die ich ĂĽbergebe hat auch nix genĂĽtzt.

Der Code sieht jetzt wie folgt aus:

Code: Alles auswählen

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace LaserTTT
{
    public partial class Form1 : Form
    {
        [DllImport("easylase.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern int EasyLaseGetCardNum();
        [DllImport("easylase.dll", CallingConvention = CallingConvention.StdCall)]
        public static unsafe extern bool EasyLaseWriteFrame(int cardNumber, byte *datapointer, int bytecount, ushort speed);
        [DllImport("easylase.dll", CallingConvention = CallingConvention.StdCall)]
        public static unsafe extern bool EasyLaseStop(int cardNumber);
        [DllImport("easylase.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern bool EasyLaseClose();

        private int easylaseCount;

        public unsafe Form1()
        {
            InitializeComponent();
            easylaseCount = EasyLaseGetCardNum();

            if (easylaseCount > 0)
            {
                byte[] frame = new byte[128000];
                for (int i = 0; i < 127999; i++)
                    frame[i] = 0;

                fixed (byte *array = frame)
                {
                    EasyLaseWriteFrame((int)0, array, (int)16, (ushort)5000);
                
                }
                
            }
            
        }

        private void Form_Closing(object sender, EventArgs e)
        {
            if (easylaseCount > 0)
            {
                EasyLaseStop(0);
                EasyLaseClose();
            }
        }
    }
}
Zuletzt geändert von jokakilla am Do 06 Mär, 2008 7:25 pm, insgesamt 1-mal geändert.

Benutzeravatar
jokakilla
Beiträge: 36
Registriert: Do 07 Aug, 2003 5:05 pm
Wohnort: Braunschweig
Kontaktdaten:

Beitrag von jokakilla » Do 06 Mär, 2008 7:20 pm

Also ich hab mal weiter geforscht. Wenn ich die AccessViolationException beim WriteFrame abfange tritt die nochmal beim EasyLaseStop(0); auf.

Es sei denn ich fĂĽhre vor dem EasyLaseStop(0) nochmal EasyLaseGetCardNum() aus.

Benutzeravatar
jokakilla
Beiträge: 36
Registriert: Do 07 Aug, 2003 5:05 pm
Wohnort: Braunschweig
Kontaktdaten:

Beitrag von jokakilla » Di 11 Mär, 2008 4:18 pm

Ich konnte das Problem mit der Hilfe von einem User von mycsharp.de lösen.

Es lag an den Parametern. Kann es sein, dass die Dokumentation der EasyLase.dll nicht richtig ist? In dem PDF steht, dass es sich bei dem cardNumber Parameter der EasyLaseWriteFrame Funktion um einen Integer handelt. Tatsächlich muss es ein Pointer auf einen Integer sein.



Naja ich werd fĂĽr den Anfang mal versuchen TicTacToe zu Programmieren um erstmal damit warm zu werden. Bin allerdings was Grafiksachen angeht nicht so erfahren.

Vielleicht habt ihr ja noch Tipps wie man am Besten mit den Punkten für die Frames als Datenstruktur umgeht, wie man sie schnell bearbeiten Transformieren kann usw. Trapezkorrektur usw. Es ist ja keine Matrix in dem Sinne weil ich nur die Punkte definiere die ich auch setzen möchte.
Ein Array mit 4096x4096 definierten Punkten ist sicherlich auch nicht besonders performant.

Habt ihr weitere Ideen welche Spiele man schön umsetzen könnte?
SuperMarioBros wär noch der Kracher ;) Aber komme eher aus einer anderen Ecke der Programmierung (Socketanwendungen, Netzwerklastgenerierung, Protokolle höherer Schichten umsetzen [SIP z.B.], ...) Hätte spontan keine Ahnung wie man das sauber umsetzt.

Code: Alles auswählen

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace LaserTTT
{
    [StructLayout(LayoutKind.Sequential)]
    public struct Point
    {
        public ushort x;    // 2 bytes, value: 0-4095 (x-coordinate)
        public ushort y;    // 2 bytes, value: 0-4095 (y-coordinate)
        public byte r;    // 1 byte, value: 0-255 (red)
        public byte g;    // 1 byte, value: 0-255 (green)
        public byte b;    // 1 byte, value: 0-255 (blue)
        public byte i;    // 1 byte, value: 0-255 (intensity)
    };

    public partial class Form1 : Form
    {
        [DllImport("easylase.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "EasyLaseGetCardNum")]
        public static extern int EasyLaseGetCardNum();
        [DllImport("easylase.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "EasyLaseWriteFrame")]
        public static extern byte EasyLaseWriteFrame(ref int cardNumber, Point [] datapointer, int bytecount, ushort speed);
        [DllImport("easylase.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "EasyLaseStop")]
        public static extern bool EasyLaseStop(ref int cardNumber);
        [DllImport("easylase.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "EasyLaseClose")]
        public static extern bool EasyLaseClose();
        [DllImport("easylase.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "EasyLaseGetLastError")]
        public static extern int EasyLaseGetLastError(ref int CardNumber);
        [DllImport("easylase.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "EasyLaseGetStatus")]
        public static extern int EasyLaseGetStatus(ref int CardNumber);
        

        private int easylaseCount;
        private int card = 0;

        public Form1()
        {
            InitializeComponent();            
        }

        private void Form_Closing(object sender, EventArgs e)
        {
            if (easylaseCount > 0)
            {
                EasyLaseStop(ref card);
                EasyLaseClose();
            }
        }

        private unsafe void button1_Click(object sender, EventArgs e)
        {
            easylaseCount = EasyLaseGetCardNum();
            MessageBox.Show(Convert.ToString(EasyLaseGetStatus(ref card)));
            if (easylaseCount > 0)
            {

                Point[] pointarray = new Point[15];
                ushort x = 2000;
                ushort y = 2000;
                byte r = 0;
                byte g = 255;
                byte b = 0;
                byte intens = 0;

                for (int i = 0; i < 15; i++)
                {
                    pointarray[i].x = x;
                    pointarray[i].y = y;
                    pointarray[i].r = r;
                    pointarray[i].g = g;
                    pointarray[i].b = b;
                    pointarray[i].i = intens;
                    x += 30;
                    //y += 30;
                }
                try
                {
                    EasyLaseWriteFrame(ref card, pointarray, Marshal.SizeOf(typeof(Point)) * pointarray.Length, 500);
                }
                catch (AccessViolationException ave)
                {
                    
                    MessageBox.Show(ave.Message);
                }
            }
        }
    }
}

Antworten

Zurück zu „Software & Programmierung“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste