Libreria con funzioni dichiarate/usate ma non definite?

di il
5 risposte

Libreria con funzioni dichiarate/usate ma non definite?

Ciao a tutti,
sto lavorando (per motivi universitari su un problema. Provo a spiegarvelo meglio che posso (tenete conto che sono un elettronico e non ho la completezza che puó avere chi lavora costantemente con linguaggi di programmazione). Il mio problema é questo: ho 2 processori che da ora in poi chiameró originale e modificato. Il primo mi é stato fornito con compilatore, linker, assembler e compagnia bella ma non é modificabile. Il secondo mi é stato fornito solo con assembler e linker. Ho modificato il processore che, per l´appunto si chiama modificato, aggiungendo delle istruzioni assembler al suo set iniziale. Premesso ció ho un programma C++ cosí strutturato:
-Una main.cpp
-Due librerie a cui si appoggia e in cui sono deinite le funzioni chiamate da main
All´interno delle cartella di queste due librerie ho due script (uno ciascuno) bash che mi compilano la libreria con comp+asm+link del processore originale creandomi la libreria.a.
Il mio problema é che vorrei utilizzare per l´applicazione il mio processore modificato, per fare ció:
-Uso il compilatore (clang++) del processore originale per compilare main.cpp stoppandolo (-S) prima dell´assembler.
-A questo punto ho un file assembly che daró in pasto all´assembler del processore modificato
-Infine useró sui file il linguaggio macchina il linker del processore originale
Fin qui nessun problema.
Il problema sorge quando nel codice dei file sorgente C++ delle librerie voglio usare delle righe di inline assembly per usare le nuove istruzioni del processore modificato. Gli script nelle cartelle della libreria usano comp+assm+link del processore originale che, ovviamente, non conosce le nuove istruzioni e mi da un errore.
Supponendo che io non voglia/possa modificare gli script nelle librerie esiste un modo in C++ con cui eventuali istruzioni assembly vengano ignorate (per poi avere un senso nella compilazione finale)?
Oppure esiste un modo per dichiarare funzioni e usarle nel codice delle librerie senza peró definirle, lasciando le definizioni pendenti nel file.a? (la definizione della funzione sarebbe in questo caso fatta nella main.cpp che, essendo compilata con l´assembler del processore modificato, riconoscerebbe le linee di inline assembly).
Probabilmente non sono stato chiaro...se avete bisogno di altre delucidazioni sono a disposizione
Gracias

5 Risposte

  • Re: Libreria con funzioni dichiarate/usate ma non definite?

    Il modo in teoria c'è, ma presuppone niente assembly inline (dato che non hai il compilatore C++ per il processore modificato).
    Ti crei un file header con le dichiarazioni delle funzioni da usare e poi scrivi direttamente in assembly il codice della funzione stessa per il processore modificato. Al momento del linking, il linker collegherà la chiamata C al codice assembly del processore modificato.
    Il modo di collegare la chiamata C alla parte assembly (inteso come passaggio di parametri da C ad Assembly può variare dall'Assembler che usi, ma al lato C della faccenda questo non interessa:
    al C è sufficiente dichiarare extern la chiamata al codice della libreria in esame.
    In pratica con:
    
    extern "C" return_type funzione(tipo_argomenti argomenti);
    
    dici al compilatore: tu compila tranquillamente il codice oggetto perché da qualche altra parte esiste il codice effettivo. Quando farai il linking, sarà il linker a fare il collegamento tra quella chiamata e il codice nella libreria modificata. Ovvio che se non esiste tale codice nella libreria modificata avrai errore.
    Per inciso è quello che in genere si fa anche con librerie esterne C, solo che nel tuo caso, non avendo un compilatore C per il processore modificato, non puoi usare assembly inline (con cosa lo compili il codice?), ma solo Assembly puro.
    La rogna adesso diventa come passare i dati C alla parte Assembly e recuperarli, ma se conosci il tuo Assembler non dovrebbe essere un problema.
  • Re: Libreria con funzioni dichiarate/usate ma non definite?

    Avevo provato una soluzione del genere ma continua a darmi degli errori. Ho cercato di capire il motivo...vediamo se sbaglio. Considerando che la compilazione si svolge in 3 fasi (le due librerie e l´applicazione principale che fa riferimento a funzioni nelle suddette librerie) se io vado a modificare una libreria devo compilarla con il suo script (cmake). In questo script ho il compilatore originale (quindi non posso usare inline assembly) e definiró le funzioni come extern. Il compilatore a quel punto suippone di trovare la definizione "da qualche parte" e procede creando la libreria.a. La sua fase di linking é quindi passata e la funzione extern non é stata definita. A questo punto quando vado a compilare l´applicazione principale questa sostituirá, ad ogni chiamata di funzione presente nella libreria, il suo codice macchina per crearne uno finale. Il compilatore per l´applicazione principale si occuperá del linking unicamente per quello che riguarda il main ma non andrá a toccare il codice macchina giá generato e i riferimenti giá risolti nella libreria. Ignorerá quindi il linking delle extern che resteranno pendenti e non definite. Forse (sicuramente) sbaglio da qualche parte ma l´errore finale é un "unresolved symbol call.." tipico di una situazione di questo tipo. Un idea che mi é venuta é...perché non modificare il cmake della libreria da modificare affinché consideri anche un libreria precompilata (con l´assembler modificato)? Sará possibile? In quel caso il linker della libreria dovrebbe sostituire unicamente codice macchina giá (correttamente) creato senza interessarsi dell´assembler (che non conosce completamente)...
  • Re: Libreria con funzioni dichiarate/usate ma non definite?

    Per essere piú chiaro i passi di compilazione sono i seguenti:
    1)libreria1 (da modificare) --->comp1+asm1+link1 -----> lib1.a
    2)libreria2 (da lasciare intatta) ---> comp1+asm1+link1 -----> lib2.a
    3)main.cpp (che usa funzioni in lib1 e lib2) -----> comp1+asm2+link1 ------>eseguibile

    Con comp intendo preprocessore, analisi lessicale etc. fino al linguaggio assembly. Ció che si ottiene tipicamente con il flag "-S" in un compilatore clang (e credo anche su gcc/g++).
  • Re: Libreria con funzioni dichiarate/usate ma non definite?

    Dino ha scritto:


    definiró le funzioni come extern. Il compilatore a quel punto suippone di trovare la definizione "da qualche parte" e procede creando la libreria.a. -- La sua fase di linking é quindi passata
    Attenzione che compilazione e linking sono processi distinti (anche se spesso il secondo si confonde con il primo).

    Di solito quel che accade è:
    il compilatore crea tutti i file oggetto;
    il linker unisce tutti questi file per creare l'eseguibile.

    Nulla però vieta di:
    dire al compilatore di creare solo i file oggetto;
    aggiungere una libreria esterna alla fase di linking;
    effettuare il linking di tutti i file oggetto + la nuova libreria.

    Ovviamente questa nuova libreria la devi prima creare sul processore modificato.
  • Re: Libreria con funzioni dichiarate/usate ma non definite?

    Hai perfettamente ragione, avevo un altro tipo di bug che mi creava dei conflitti tra simboli delle due librerie. Con "extern" va tutto benissimo. Spiego la soluzione cosicché magari qualcuno potrá trarne beneficio in futuro per problemi simili:
    -Ho 2 librerie e un file main.cpp che si appoggia a queste
    -Voglio modificare i file sorgente delle librerie inserendo inline assembly con istruzioni note SOLO all´assembler di main.cpp
    -Le librerie sono compilate con due script che usano un assembler diverso da quello della funzione main, non posso quindi inserire nei file sorgente direttamente l´inline assembly poiché questo non sarebbe riconosciuto (a meno di modificare gli script indirizzandoli ad utilizzare l´assembler di main.ccp)
    -Dichiaro le funzioni all´interno dei file sorgente delle librerie come EXTERN e le chiamo quando mi servono
    -Definisco le funzioni all´interno del main usando l´inline assembly (conosciuto dall´assembler di main.cpp quindi nessun errore)
    -Il linker di main.cpp sostituira alle funzioni extern nei file di libreria il corretto linguaggio di macchina (che ora conosce essendo giá stato eseguito l`assembler di main.cpp)

    Era dovere di chiarezza. Sono sicuro di non aver usato le terminolgie piú adatte ma spero si capisca il senso.
    Grazie mille
Devi accedere o registrarti per scrivere nel forum
5 risposte