Ich habe eine Klasse erstellt, die wie ein Array aussieht, aber anstatt die Daten im Programm selbst zu speichern, streamt sie das Byte aus einer Datei (um den RAM-Einfluss zu reduzieren). Jetzt habe ich all diese Arbeit bekam, aber der Programmierer muss die Klasse definieren mit dem folgenden:Erstellen von Template-Parametern zum Zeitpunkt des Kompilierens
#define CreateReadOnlyBlock(name, location, size, ...) \
template<> \
const unsigned int ReadOnlyBlock<location, size>::Data[] \
__asm__(".readonly__" #location "__" #name) \
= { __VA_ARGS__ }; \
ReadOnlyBlock<location, size> name;
Beispiel:
//A read only array of {0, 1, 2, 3}
CreateReadOnlyBlock(readOnlyArray, 0, 4, 0, 1, 2, 3);
Beachten Sie, dass dies für einen Embedded-Prozessor ist, und die asm-Richtlinie durchläuft ein Tool im Assembler, um die schreibgeschützte Datei zu erstellen.
Also hier ist meine Frage: Wie kann ich die Variablen "Standort" und "Größe" beseitigen? Ich hasse es, dass der Programmierer diese manuell eintippen muss, und würde es viel lieber bevorzugen, diese zur Kompilierzeit zu erzeugen. Anstatt also den Programmierer zu geben brauchen:
//A read only array at location 0 of {0, 1, 2, 3}
CreateReadOnlyBlock(readOnlyArray1, 0, 4, 0, 1, 2, 3);
//A read only array at location 4 of {4, 5, 6, 7}
CreateReadOnlyBlock(readOnlyArray2, 4, 4, 4, 5, 6, 7);
Sie konnten nur geben:
CreateReadOnlyBlock(readOnlyArray1, 0, 1, 2, 3);
CreateReadOnlyBlock(readOnlyArray2, 4, 5, 6, 7);
und die entsprechenden Konstanten erzeugt werden würde. Im Grunde suche ich nach einer Möglichkeit, diese Konstanten auf der Basis früherer Definitionen zur Kompilierzeit zu erzeugen und zu platzieren. C++ 11 ist ein faires Spiel, ich kenne es nicht besonders gut (etwas mit conetexpr scheint plausibel?). Auch C-Preprocessor ist in Ordnung, wenn es es nicht hässlicher macht, als es bereits ist. Ist das möglich?
EDIT für Klarheit:
In der ReadOnlyBlock Klasse gibt es diese Methode:
template<const int _location, const int _size> class ReadOnlyBlock
{
...
unsigned int operator[] (size_t index)
{
return LoadFromROM(index + _location);
}
}
Es ist eine intrinsische gegenseitige Abhängigkeit zwischen dem Ort Größe und der ROM-Datei, die ich nicht denken kann, wie zu brechen. I tun haben vollständige Kontrolle über die Werkzeugkette aber auch, aber ich brauche eine Möglichkeit, das Assembler-Tool zu übergeben, wie die Datei zu konstruieren sowie auf den C++ Code anzuzeigen, wo die Blöcke in der Datei liegen.
Ein weiterer EDIT:
Die Datei und die Blöcke können sein ganz groß, so viel wie 1k Worte, so viele Präprozessor Magie könnte, dass Zusammenbruch gegeben. Danke auch allen für die bisherige Hilfe!
Die '# location' im '__asm__' Teil bringt es wirklich um. Brauchst du das wirklich oder würdest du nur mit einer Lösung des Rests zufrieden sein? –
Die Größe ist einfach, aber die Position würde Kontext erfordern. Die Template-Instanziierung ist eine funktionale Sprache, und das Ergebnis der Instanziierung kann nur davon abhängen, was Sie übergeben. Wenn Sie solche Blöcke verketten oder den Speicher in einer großen Vorlage erstellen, kann dies geschehen. Dh, erstellen Sie ein "Tupel" von Nur-Lese-Arrays, jedes mit einem Ort und einer Größe, beginnend an einer bestimmten Stelle, und gepackt. – Yakk
Also vielleicht hätte ich den Grund dafür angeben sollen. Der überladene [] -Operator in der ReadOnlyBlock-Klasse ruft LoadFromROM auf (index + location); Das Tool erstellt eine schreibgeschützte Datei, die jeden Block an jedem angegebenen Speicherort enthält, und die Klasse kann von diesem Punkt aus laden. Ich kann mir keinen Weg vorstellen, diese gegenseitige Abhängigkeit zu beseitigen, aber ich habe die volle Kontrolle über das Tool und den Zugriffscode, so dass es nicht unmöglich ist, sie zu ändern. –