ctemplate.h
pl
- sonstiges
Hi, etwas OT, es geht um eine Templating Engine in c mit der ich grad die ersten Schritte tu.
Problem macht die Funktion TMPL_write("tmplfile", 0, 0, mylist, stdout, stderr);
die Templatedatei wird einfach nicht gefunden, egal ob ich mit relativen oder absoluten Pfadangaben arbeite.
Da bin ich echt ratlos, vielleicht hat ja jemand eine Idee dazu. Ansonsten funktioniert das Teil ganz wunderprächtig mit Templates die auch zu HTML::Template
passen.
MfG
> TMPL_write("tmplfile", 0, 0, mylist, stdout, stderr);
Kann an der 0 liegen. Im Handbuch steht:
Parameter filename is the name of the template file. If parameter tmplstr is non-null, then it is the template, a null terminated string.
Dieses "null" ist, als Begriff, ziemlich dehnbar. Versuchs mal mit gar nichts zwischen den Kommas (,,
) , null
, "" oder ''.
TMPL_write("tmplfile",, 0, mylist, stdout, stderr);
TMPL_write("tmplfile", null, 0, mylist, stdout, stderr);
TMPL_write("tmplfile", '', 0, mylist, stdout, stderr);
TMPL_write("tmplfile", "", 0, mylist, stdout, stderr);
Danke Dir, isn Ansatz. Ob diese Lib auch für c++ geeignet ist, wäre dann die nächste Frage.
MfG
hi fastix,
so langsam werd ich wieder warm mit c 😉
Eine 0 in char *string = 0
ist völlig Ok, 1. wird der Pointer initialisiert und 2. funktionieren damit die Kontrollstrukturen. D.h., ein if(string)
würde immer wahr ergeben wenn string = ""
(Leerstring) ist und das ist schlecht. Mit 0 initialisiert hingegen klappt das einwandfrei.
Gleichermaßen verhält es sich mit den Rückgabewerten von Funktionen wenn das Stringspointer sein sollen char *func(){}
. So gibt es ein return 0;
wenn meine Funktion beim Durchlaufen einer verketteten Liste den gesuchten String nicht gefunden hat ansonsten einen Zeiger auf den String.
Was ctemplate.c
betrifft, so nehme ich zum Lesen der Templatedatei nun eine eigene Routine weil ich eine Solche ohnehin auch anderweitig brauche.
Mein Web Framework in c -- das ist der Plan. Da werde ich mal weitermachen, bis jetzt sieht das schon ganz gut aus, d.h., das Ausliefern bestimmter Seiten per c fügt sich nahtlos in das FW ein was ansonsten in Perl geschrieben ist.. vom Tempo her genauso schnell als würde der Apache die Seite selbst ausliefern und nicht über die CGI Schnittstelle schleifen.
MfG
Moin pl,
Eine 0 in
char *string = 0
ist völlig Ok, 1. wird der Pointer initialisiert und 2. funktionieren damit die Kontrollstrukturen. D.h., einif(string)
würde immer wahr ergeben wennstring = ""
(Leerstring) ist und das ist schlecht. Mit 0 initialisiert hingegen klappt das einwandfrei.
In C gibt es auch keine Strings, sondern nur Arrays von Zeichen – und ein Array ist letztlich nur ein Pointer auf die erste Position der Elemente. Als „String“ wird ein Zeichenarray betrachtet, dessen letztes Zeichen 0 ist. Daher ist ""
auch ein Zeichenarray der Länge 1, bestehend aus dem NULL-Byte und mit einer von 0 unterschiedlichen Position im Speicher. Dein Vergleich if(string)
müsste daher in C heißen
if (strlen(string)) {
/* … */
}
Gleichermaßen verhält es sich mit den Rückgabewerten von Funktionen wenn das Stringspointer sein sollen
char *func(){}
. So gibt es einreturn 0;
wenn meine Funktion beim Durchlaufen einer verketteten Liste den gesuchten String nicht gefunden hat ansonsten einen Zeiger auf den String.
Vorsicht:
char* func(char *arg) {
char intern[23];
static char ext[42];
char *dynamic = (char*) malloc(42);
/* Führt zu undefiniertem Verhalten, weil die Variable nur im Scope der Funktion existiert:
* return intern;
*/
/* Funktioniert, erfordert aber ggf. eine Kopie des statischen Strings:
* return ext;
*/
/* Funktioniert, String muss aber nach Verwendung freigegeben werden um Memoryleaks zu vermeiden:
* return dynamic;
*/
return 0;
}
Viele Grüße
Robert
hi danke,
Überraschungen gibt es natürlich 😉 Btw., mein gcc gibt Warnung, wenn eine Variable returned werden soll die nur im Scope der Funktion existiert.
MfG
Btw., in meiner Konfiguration lege ich Namen von Funktionen fest. Gibt es in c eine Möglichkeit, mit einem konfigurierten Namen eine gleichnamige Funktion aufzurufen? Also unmittelbar?
Bitte mal um Hinweises.
Tach!
Btw., in meiner Konfiguration lege ich Namen von Funktionen fest. Gibt es in c eine Möglichkeit, mit einem konfigurierten Namen eine gleichnamige Funktion aufzurufen? Also unmittelbar?
Dazu müsste C über Reflection verfügen. Da es das da nicht gibt, geht die Information zu Namen beim Compilieren verloren.
dedlfix.
Nein eval meinte ich nicht. Sondern vielmehr sowas execute('Functionsname')
. Die übliche Vorgehensweise besteht darin, anhand Funktionsname
zu ermitteln ob es eine solche Funktion im aktuellen Namespace gibt. Das kann sogar PHP und im Ergebnis einer solchen Prüfung bekommt man eine Referenz auf den Code den man somit ausführen kann.
Sowas für c oder c++
PS: Für c++ nicht die Methode sondern die Instanzerstellung anhand Namen einer Klasse.
Nein was Du gefunden hast, ist es leider nicht. Aber danke totzdem.
Hallo pl,
PHP und JavaScript sind Scriptsprachen, die sich auf gewaltige Dictionaries stützen. Das kostet Zeit, bringt aber die Flexibilität dieser Sprachen.
C ist ein Makroassembler mit großer Laufzeitbibliothek und einigem Geschick beim Hantieren mit Expressions, die zu einzeiligen Programmen beliebiger Komplexität führen können.
D.h. wenn Du Funktionen namentlich aufrufen können willst, dann
Ich weiß gerade nicht ob C sowas im Bauch hat; C++ hat in der STL sicherlich Klassen für ein string->func* Dictionary.
func* ist ein Zeiger auf eine Funktion. Mein C ist arg eingerostet und die Notation ist hinreichend verquast, such Dir Beispiele. Du kannst dann im Dictionary Einträge machen aus Name und Zeiger auf Funktion, und dann an Hand dieses function pointers die Funktionen aufrufen. Ich bezweifle dass es stimmt, aber ich definiere mal für mein Beispiel, dass int(*)(int,int,int) einen Pointer auf eine Funktion darstellt, die 3 int bekommt und eins zurück gibt. Ganz weit weg von der Wahrheit bin ich vermutlich nicht. Damit hantierst Du dann so:
int(*)(int,int,int) func = getRegisteredHandlerFor(name);
int result = (*func)(47,11,42);
Ob die Klammern um *func nötig sind weiß ich nicht - Beherrschung der Operatorenhierarchie von C gehört zu den arkanen Künsten. Und sowohl * (dereference pointer) und () (call function) sind (überladbare) Operatoren. Beide haben hohen Rang, aber aus Sicht eines kleinen plus und minus ist das so weit weg dass man nicht mehr erkennt wer nun höher ist. Lieber Klammern setzen bevor Du versuchst, ein int-Ergebnis als Pointer zu behandeln und zu dereferenzieren. Hier würde immerhin der C-AssemCompiler Einwände erheben, bevor es zum Bluescreen kommt.
Wenn es typsicher bleiben soll, dann ist diese Suchfunktion nur für Funktionen einer Signatur geeignet. Idiomatisch für idiotisches C wäre aber, diese function pointer als void* zu speichern und bei Bedarf auf einen function pointer mit der (vermeintlich) richtigen Signatur zu casten. TU'S NICHT!
C und C++ sind leider sehr viel sensibler, was Typen angeht, als JavaScript, PHP oder Perl.
Eine C-Library in C++ verwendest Du übrigens prinzipiell so:
extern "C" {
#include <lib.h>
}
Rolf
Alte Liebe c 😉
Ein CGI in c kompiliert läuft genauso flott wie ein FastCGI.
MfG
Ein CGI in c kompiliert läuft genauso flott wie ein FastCGI.
Wenn Du nicht persistent bist, bist Du nicht persistent.
Ein CGI in c kompiliert läuft genauso flott wie ein FastCGI.
Wenn Du nicht persistent bist, bist Du nicht persistent.
Es ist mir ein besonderes Vergnügen, meine Perlklassen persistent zu machen!
Wenn Du nicht persistent bist, bist Du nicht persistent. Es ist mir ein besonderes Vergnügen, meine Perlklassen persistent zu machen!
Ah... welche Sicherheitslücke welchen Webservers nutzt Du genau?
Hallo pl,
Btw., in meiner Konfiguration lege ich Namen von Funktionen fest. Gibt es in c eine Möglichkeit, mit einem konfigurierten Namen eine gleichnamige Funktion aufzurufen? Also unmittelbar?
Wäre eine DLL/ein Shared-Object für dich unmittelbar genug? Dort werden die exportierten Funktionsnamen über Strings aufgelöst, siehe https://en.wikipedia.org/wiki/Dynamic_loading bzw. für Unix konkret dlopen, dlsym und dann dlclose
#include <dlfcn.h>
typedef
void *lib;
if ((lib = dlopen("lib<myname>.so", RTLD_LAZY))) {
void *fct;
if ((fct = dlsym(lib, "FunctionName"))) {
// verwende das aufgelöste Symbol
// …
}
dlclose(lib);
}
Viele Grüße
Robert
Danke Euch bisher!
Hi, etwas OT, es geht um eine Templating Engine in c mit der ich grad die ersten Schritte tu.
Problem macht die Funktion
TMPL_write("tmplfile", 0, 0, mylist, stdout, stderr);
die Templatedatei wird einfach nicht gefunden, egal ob ich mit relativen oder absoluten Pfadangaben arbeite.
Das Problem hat sich in Luft aufgelöst 😉 D.h., es funktioniert nun tadelfrei, weiß der Geier warum das die Tage nicht ging.
MfG
@Robert B. ja, c ist tückisch 😉
Speicherbreiche müssen typegerecht und akkurat definiert sein, sonst knallts 😉
Vielleicht hat ja noch jemand ne Idee hinsichtlich assoziativer Datenstrukturen. Ich habe hier eine EAV Tabelle als indizierte Liste im Hauptspeicher, die muss jedesmal komplett durchlaufen werden wenn zu einem Entity/Attribute ein bestimmter Value gebraucht wird.