Ich suche nach einer einfachen Möglichkeit möglichst aus einer einfachen C-Funktion (Loadable Extension Function bzw. Virtual Table in der embedded database engine SQLite3) heraus einen String auf den einzigen (bzw. einen bestimmten von mehreren) Druckerport schicken zu können. Da ich meine LEF in C sowohl mit Delphi (BDS2006) unter WinXP als auch Linux compilieren, binden und benutzen kann, sollte die Lösung möglichst plattformunabhängig sein. Kann mir jemand sagen, wie ich das am elegantesten umsetzen kann? - Habe in einem anderen Beitrag bereits etwas mit fopen("prn","w") gefunden, aber ist das eine solche Lösung? Oder ist prn nur unter Win bekannt? Meine Anwendung sieht so aus, daß ich von mehreren Druckern die Daten (parallel-seriell gewandelt, inclusive aller Steuerzeichen für den Drucker) einsammle und zwischenspeichere und dann in einem Rutsch jeweils eine komplette Seite drucken will, sobald dafür die Datenmenge ausreichend ist.
Mach den Drucker-Device-File in /dev auf und schreib dort deinen Text rein.
Ich bin in Linux noch nicht sehr firm, daher frage ich. Meine Bücher haben mir da leider noch nicht sehr viel weiter geholfen oder ich habe die entsprechenden Stellen übersehen. Wie heißt das Device-File des Druckers? Gibt es in Linux so etwas ähnliches wie in Windows, wo ein "Generic Text"-Drucker eingerichtet werden muß? Oder gibt es den schon im Standard? Es handelt sich in meinem Falle um Fedora Linux. Am Ende öffne ich mit hFile=fopen("/dev/????","w") und kann dann mit fwrite(hFile,"string") auf die Druckerschnittstelle schreiben und mache dann mit fclose(hFile) wieder zu; ist das richtig?
Den Unfug findest du unter Linux so nicht. Wenn du einen Schnittstelle öffnest, ist das dann halt so, Punkt aus und Ende. Da pfuscht dir kein Druckertreiber mehr dazwischen. Ordentlich Drucken tut man deshalb z.B. mit dem Drucksystem CUPS, das sorgt dann dafür, dass einer nach dem Anderen druckt. Außerdem werden die Druckdaten vorher dem Drucker mundgerecht aufgearbeitet.
Erst einmal Danke. Leider hilft mir das mit CUPS nicht viel weiter, denn ich habe erst Anfängerkenntnisse mit Linux. Eher schon hilft mir das mit dem /dev von uhu, sofern ich noch in Erfahrung bringen kann, wie der Teil heißt, der dahinter noch fehlt. Die Daten, die ich zwischengespeichert habe, sind ja schon für den entsprechenden Druckertyp (Nadeldrucker) aufbereitet. Lediglich habe ich viele davon von verschiedenen Eingängen und sammle sie alle in einer SQLite3-Datenbank, bis für einen davon soviele beisammen sind, daß sie eine ganze Seite füllen. Ich habe also die aufbereiteten Daten für eine ganze Seite beisammen in einem String. Doch wie bekomme ich den an den Druckerausgang? Und zwar aus einer C-Funktion heraus!? Alternativ könnte ich die Funktion system("") auch mit einem (mir bisher noch unbekannten) bash-Kommando füllen und aufrufen, aber das wäre keine direkte sondern eine indirekt Ausführung, was ich lieber vermeiden möchte. Wonach muß ich in /dev suchen, um den Druckerausgang zu finden?
> Erst einmal Danke. Leider hilft mir das mit CUPS nicht viel weiter, denn > ich habe erst Anfängerkenntnisse mit Linux. http://tldp.org/HOWTO/Printing-Usage-HOWTO-2.html
Teste mal /dev/lp*n* wobei n die Windoofportnummer -1 ist.
Rolf, danke für den Link. Habe (per VPN und PuTTY-SSH) mal unter /dev nachgeschaut. Ich finde lp0 bis lp3, parport0 bis parport3 und port aber nicht wie beschrieben lp oder print. Ich kann auch mit lpr und lpq keine Info über angeschlossenen Drucker bekommen. Ich denke, das ist noch nicht installiert. Funktioniert dann lp0 für den Parallelport auf dem Mainboard trotzdem? Worin besteht der Unterschied zwischen /dev/lp0 und /dev/parport0? Ist /dev/port vielleicht die richtige Wahl. Ich würde mich sehr freuen, wenn mir da einer weiterhelfen könnte eine Antwort drauf zu bekommen. Danke.
Sag mal, hast du das Ganze auch mal probiert? Ich mein, ein
1 | #include <stdio.h> |
2 | #include <stdlib.h> |
3 | |
4 | int main(int argc, char *argv[]) |
5 | {
|
6 | FILE *fp; |
7 | |
8 | fp = fopen("/dev/lp0", "w"); |
9 | if (!fp) { |
10 | perror("Cannot open /dev/lp0"); |
11 | return EXIT_FAILURE; |
12 | }
|
13 | |
14 | if (fwrite("Test", 4, 1, fp) != 4) { |
15 | perror("Could not write to /dev/lp0"); |
16 | return EXIT_FAILURE; |
17 | }
|
18 | |
19 | fclose(fp); |
20 | |
21 | return EXIT_SUCCESS; |
22 | }
|
ist doch jetzt schnell getippt ... und kompiliert. Bernhard
>Sag mal, hast du das Ganze auch mal probiert?
Nein, kann ich nicht so einfach, denn das Ganze wird auf einem Rechner
in Malaysia ausgeführt werden und der ist aktuell bis Januar
ausgeschaltet und ein anderer Rechner, der mir als Entwicklungsrechner
dient, ist anders angeschlossen.
Den Namen des Devicefiles kann man leider nicht ex cathedra verkünden - die variieren je nach Distribution. lp<n> und parport<n> sind gute Kandidaten. Um herauszufinden, welcher File zum Drucker gehört, kann man folgendes Kommando probieren: echo "Hurra, er druckt" >/dev/printer Man muß eben für printer die Device-Files durchprobieren, die möglicherweise zum Drucker gehören.
Natürlich weißt du die Nummer der Gerätedatei nicht vorher weil ein Computer über mehrere Parallelports verfügen kann. Das ist aber unter Windows das Gleiche, du musst in deinem Programm wohl eine Option vorsehen. /dev/parportN und /dev/lpN sind aber was ganz anderes. Während /dev/parportN Dir den direkten Zugriff auf den Parallelport gibt (der zugehörige Treiber heißt "ppdev" und normalerweise solltest du /dev/parportN nicht direkt über entsprechende ioctl()-Aufrufe verwenden sondern über die libieee1284) ist /dev/lpN nur für Drucker gedacht. Dafür kümmert sich hier der Treiber von selber um Steuerleitungen und Handshaking während du das bei /dev/parportN selber machen müsstest. Zur Druckeransteuerung deshalb /dev/lpN, für sonstige Geräte am Parallelport wie ein Scanner oder auch ein ZIP-Laufwerk (wobei es hier einen entsprechenden Kerneltreiber gibt da man das Ganze dann ja als Blockdevice ansprechen muss) oder irgendwelche Basteleien /dev/parportN. Dass sich die Nummern je nach Distribution unterscheiden bezweifle ich. Sicherlich kannst du über enstpechende Udev-Regeln da alles mögliche machen oder statt erst udev gar nicht verwenden, neue Distributionen sind aber in dem Punkt hinreichend gleich so dass /dev/lp0 in 99.9 % der Fälle der erste und einzige Parallelport des Mainboards ist. Wie LPT1 halt unter Windows. Bernhard
Uhu, danke für diesen Tip. So hatte ich das unter WinXP auch probiert, um den Parallel-Seriell-Converter zu testen; Ausgabe auf LPT1: umgeleitet. Bernhard, danke für Deine Erklärungen, das macht für mich Sinn und beantwortet meine Fragen. Werde das erst einmal mit lp0 und Knoppix ausprobieren und mir dann von meinem Assistenten in Malaysia zurückmelden lassen, ob und wie das Ergebnis auf dessen Drucker aussieht.
> Ich kann auch mit lpr und lpq keine Info über angeschlossenen > Drucker bekommen. Ich denke, das ist noch nicht installiert. Ja. Dazu müßte der passende Druckertreiber eingerichtet sein. > Funktioniert dann lp0 für den Parallelport auf dem Mainboard > trotzdem? Ja.
Bernhard Walle wrote:
> Dass sich die Nummern je nach Distribution unterscheiden bezweifle ich.
Na ja, es ist ja immerhin möglich, daß es einen USB- und einen
Parallel-Drucker gibt - schon ist die Eindeutigkeit dahin und hängt von
der Distribution ab.
Uhu Uhuhu wrote: > Bernhard Walle wrote: > >> Dass sich die Nummern je nach Distribution unterscheiden bezweifle ich. > > Na ja, es ist ja immerhin möglich, daß es einen USB- und einen > Parallel-Drucker gibt - schon ist die Eindeutigkeit dahin und hängt von > der Distribution ab. Ein USB-Drucker erhält die Gerätenamen /dev/usblpN, insofern besteht da kein Konflikt. Wenn du das Programm wirklich universell verwendbar haben willst machst du (sofern es ein GUI-Programm ist) eine editierbare Combobox die alle verfügbaren Parallelports anbietet (/dev/lpN und /dev/usblpN) und zugleich die Möglichkeit bietet, für Expertennutzer eigenen Ports anzugeben. Für die Kommandozeile oder über eine Konfigurationsdatei kannst du eine Option angeben über den man direkt den Gerätenamen einstellen kann. Default ist natürlich /dev/lp0, was eben in 95 % der Fälle der gewünschte Drucker ist. Bernhard
Danke für eure Tips. Ich habe einfach mal ausprobiert mit meiner verfügbaren Funktion, die ich sonst zum Loggen in eine Datei verwende, auf /dev/lp0 zu schreiben. Es gab keine Fehler aber leider kann ich das Ergebnis nicht einfach so begutachten, denn die Geräte stehen in anderen Ländern. Ich lasse es Euch wissen, sobald ich Testgelegenheiten hatte.
Bernhard Walle wrote: >> Na ja, es ist ja immerhin möglich, daß es einen USB- und einen >> Parallel-Drucker gibt - schon ist die Eindeutigkeit dahin und hängt von >> der Distribution ab. > > Ein USB-Drucker erhält die Gerätenamen /dev/usblpN, insofern besteht da > kein Konflikt. Dann wirst du mir sicher erklären können, warum es auf meinem Ubuntu 7.10 ein /dev/lp0 gibt, obwohl die Maschine keine parallele Schnittstelle hat.
Uhu Uhuhu wrote: > > Dann wirst du mir sicher erklären können, warum es auf meinem Ubuntu > 7.10 ein /dev/lp0 gibt, obwohl die Maschine keine parallele > Schnittstelle hat. Weil die Schnittstelle vermutlich existiert (von den I/O-Ports her) und nur nicht nach außen geführt wird. Bernhard
Welcher Gruppe muß ein User angehören, um auf /dev/lp0 senden zu dürfen? Von der seriellen Schnittstelle /dev/ttyS0 meine ich zu wissen, das es uucp ist aber welche ist es für die parallele Schnittstelle?
Manfred wrote: Hallo, > Welcher Gruppe muß ein User angehören, um auf /dev/lp0 senden zu dürfen? > Von der seriellen Schnittstelle /dev/ttyS0 meine ich zu wissen, das es > uucp ist aber welche ist es für die parallele Schnittstelle? michael@ernie01:~> ls -l /dev/lp0 crw-rw---- 1 root lp 6, 0 2005-03-19 23:01 /dev/lp0 ^^ Da würde ich glatt mal behaupten das ist die Gruppe lp. Gruesse, Michael
Danke, da hätte ich ja glatt selbst drauf kommen können.
Das mit dem Senden auf /dev/lp0 funktioniert hervorragend. Ja, es war die gruppe lp der ich meinen user zufügen mußte, so wie zuvor der uucp für den Zugriff auf serielle Schnittstellen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.