Newsgroup: it.comp.lang.c
Titolo: Nuovamente, file .lib

Ho nuovamente problemi con l'utilizzo delle librerie sotto il compilatore
Borland Turbo C++ 1.01
Come mi avete spiegato voi tempo fa in questo stesso NG, ho compilato la mia
libreria e grazie a Tlib.exe ho incluso il file oggetto (.obj) in un file
.lib.
Quando utilizzo la libreria il compilatore trova i prototipi nel file header
e fin qui tutto fila liscio; al contrario il linker non trova il codice
delle mie funzioni e si blocca. Il problema (almeno da come la vedo io) è
che il linker non cerca neanche dentro il mio file .lib nonostante lo abbia
posizionato nella cartella \tc\lib. Come posso comunicargli di includere il
mio file libreria?
Grazie a chi si interesserà, Giuseppe
P.S. Tutto ciò mi sembra strano perchè le lib standard le linka senza alcun
accorgimento nei files .h

 al contrario il linker non trova il codice delle mie funzioni e si blocca.
Devi includere le tue librerie nel progetto. Oppure, se usi il
compilatore a linea di comando, devi specificarle appresso ai tuoi file
sorgente. Quelle standard invece le utilizza automaticamente.
EMG

sorgente. Quelle standard invece le utilizza automaticamente.
Utilizzando il linker dalla linea di comando non c'è problema. Quando invece
creo un progetto e aggiungo i sorgenti e il mio file libreria (se aggiungo
gli header tenta di compilarli e non trovando main si blocca), l'IDE non
considera il mio file .lib e torna a dare il solito errore.
Inoltre, se vado a controllare nelle opzioni del file libreria incluso nel
progetto, trovo impostato il compilatore come programma di gestione del
file. Ho provato a configurare il linker come nuovo "translator" ma mi sono
perso tra i parametri.... :-(
Qualcuno che utilizza (o ha utilizzato) il Turbo C++ 1.01 sa come fare?
Grazie in anticipo, Giuseppe

 wrote in message
7k83gf$300$3...@hermes.iol.it...

Purtroppo uso il successore BorlandC++3.1, non so se e' uguale ma con
quest'ultimo funziona cosi':
nel tuo project inserisci tutti i .C del tuo applicativo e i .LIB
(specificando l'estensione), se la libreria e' nella dir corrente non devi
fare altro, altrimenti in Option/Directory devi specificare il percorso per
i .LIB, separandolo con un punto e virgola ';' da quello che gia' c'e'
scritto (cioe' C:\TC\LIB credo)
ciao
donCiccio

scritto (cioe' C:\TC\LIB credo)
Ho fatto come hai detto ma il compilatore (o meglio il linker) continua ad
ignorare il file libreria. Ho provato ridefinire i tipi di chiamata (ho
pensato chissà, forse devo specificarlo) come pascal (sia nell'.h, nel .c e
nel .lib): niente.
Allora sono passato alla riga di comando utilizzando Tcc e Tlink. Dopo vari
tentativi falliti miseramente ho notato con orrore che nè nei parametri del
compilatore nè del linker esiste un'opzione che permette di includere le
librerie non standard. Solo nel compilatore esiste la possibilità di
definire il percorso delle librerie, cosa che non mi interessa perchè, per
sicurezza, ho posto la mia libreria in \tc\lib.
Non so proprio come fare. Devo rassegnarmi a non poter utilizzare le
librerie? Qualcuno sa come fare?
Grazie per l'interessamento, Giuseppe

 librerie non standard.
Guarda meglio la sintassi del TLink:
Syntax:  TLINK objfiles, exefile, mapfile, libfiles
Come vedi č possibile specificare le librerie tra i parametri a linea di
comando.
EMG

EMG
Vero, ma non riesco. Non capisco se devo utilizzare le virgole o no (se non
le utilizzo pensa che gli stia specificando un file oggetto e non lo
riconosce come valido).
Ho provato con:
tlink E:\prova.obj, , , E:\tc\lib\prova.lib
con
tlink E:\prova.obj, E:\prova.exe, E:\prova.map, E:\tc\lib\prova.lib
e via dicendo, ma lui mi da sempre il messaggio:
Error: Undefined symbol stampa(unsigned char far*) in module \PROVA.CPP
oppure
Bad object file e:\tc\lib\prova.lib
a seconda di come metto le virgole.
Qualcuno di voi saprebbe dirmi come farebbe (la linea di comando corretta)?
Grazie ancora.
Ciao, Giuseppe

Se hai i seguenti file:
  mylib.h
  mylib.lib
Li metti nella stessa dir del tuo applicativo. Nei tuoi sorgenti scrivi
semplicemente
  #include "mylib.h"
mentre nel project inserisci:
  applicativo.c
  mylib.lib   ->specificando l'estensione
A questo punto non serve altro, almeno nel BorlandC++3.1.
Se dopo il make (tasto F9) ottieni ancore l'errore:
  linker error: undefined simbol xxx
allora prova ad eseguire:
  TLIB mylib,con
che ti restituisce a video (con) l'elenco di tutti i simboli presenti in
libreria.
Per essere linkabili con un sorgente C devono cominciare con almeno un '_'
(underscore).
Se i nomi non corrispondono alle funzioni del .H, bhee' dimmi cosa vedi e
vediamo di fare qualcosa.
ciao
donCiccio

...

Nella mia libreria (prova.lib in \tc\lib) ho solo un funzione dichiarata
come void pascal stampa(char *s) e un file header prova.h in \tc\include.
Facendo come mi hai detto tu a video avevo:
Publics by module
Prova    size=28
STAMPA
Mi era venuto il dubbio che il linker non trovasse la funzione a causa delle
maiuscole (stampa STAMPA) e ho ricompilato tutto creando la libreria con
l'opzione /C (case sensitive library). Nulla, visualizza sempre "STAMPA" e
nessun miglioramento col linker. Ho provato ad aggiungere l'underscore.
Nulla ancora. Ho riprovato in vari modi combinando underscore e maiuscole.
Nada.
Comunque non credo di dover aggiungere l'underscore perchè il linker dice
cerca stampa non _stampa (mentre invece di solito aggiunge l'underscore; un
esempio è  "undefined simbol  _main in module ecc.").
Cosa puoi consigliarmi di fare ora?
Grazie per l'interessamento.
Ciao, Giuseppe

 Error: Undefined symbol stampa(unsigned char far*) in module \PROVA.CPP
Allora vuol dire semplicemente che quella funzione (stampa) con
esattamente quel tipo di parametro non esiste nella tua libreria.
Attenzione che stai compilando implicitamente in modalità C++ a causa
dell'estensione CPP che hai dato ai files.
EMG

EMG
il trucco e' proprio li: in c++ la tua funzione
  extern int stampa ( unsigned char far* );
prende il nome:
  @stampa$qnuc
e non lo STAMPA che vedi nella tua lib, perche' nel c++ ogni funzione e'
differente da una omonima  se ha parametri e valore di ritorno differenti,
cioe' e' come se avesse un'altro nome (ed il compilatore gli da proprio un
altro nome).
prova a dichiarare nel tuo .H
extern "C"
{
  int pascal stampa ( unsigned char far* );
};
Il che dovrebbe dire al compilatore che la tua funzione e' per l'appunto in
formato C e non C++ e con calling convention pascal, cioe' no underscore e
nome tutto maiuscolo.
Altre strade:
- ricompila la lib in c++
- non compilare il tuo applicativo in c++.
ciao
donCiccio

EMG
Per essere sicuro ho dichiarato esplicitamente il tipo di chiamata (pascal),
ho provato a mettere l'underscore e altri accorgimenti (vedi al mia risposta
a Don Ciccio del 18/6). Ora riproverò con questi accorgimenti dalla riga di
comando.
Sto compilando in modalità C++ ma con questo non dovrebbe cambiare nulla. O
no?
Ciao e grazie per l'interessamento, Giuseppe

donCiccio
Ora funziona. Sono riuscito a compilare il programma correttamente!!!! :-)
Ho ricompilato il tutto con extern "C" e funziona. :-P
Ringrazio di cuore tutti coloro che mi hanno aiutato e spero un giorno o
l'altro di poter ricambiare il favore.
Grazie e ciao, Giuseppe