Guarda, con tutti i sorgenti C che ho visto le definizioni di funzione vanno tutte in file header (.h). I .cpp sono sorgente puro e semplice; gli header sono più che altro "librerie", ma non so se sia tanto corretto chiamarli così.
Per lavoro ho dovuto imparare ad usare VS2008 (Visual Basic, quindi lontano più o meno 3 anni luce da quello che devi fare tu
), però bene o male qualcosa so. Quello che ho capito è che in VS esistono molti modi per fare la stessa cosa, e i codici si assomigliano un po' tutti. Solo, il Visual Basic è più facile da leggere ed interpretare. Un consistente svantaggio è che non è poi così potente.
Per snellire il codice si possono mettere le funzioni in altri file?
Per snellire il codice si
dovrebbe mettere le funzioni in altri file. Specialmente quelle richiamate spesso, come rounding, comparazioni, manipolazioni di stringhe. Nel caso di Visual C++ in file header. Per quanto riguarda Visual Basic il discorso è un po' più complesso. Esistono porzioni di codice che si chiamano
moduli, che possono andare nello stesso
namespace dell'assembly principale, oppure ti puoi creare i .dll separati che contengono funzioni o fungono da database di array o di equazioni (cioè funzioni che restituiscono un valore). In quest'ultimo caso ci ho messo un po' per capire come si doveva fare.
Praticamente, apri un altro progetto e decidi di salvarlo come "Libreria Windows". L'interfaccia creerà automaticamente un ambiente che ti permetterà di salvare tutte le funzioni in un file .dll. E qua arrivano i casini.
Il .dll dovrebbe essere indipendente dall'eseguibile principale,
e preferibilmente anche da altri dll, 1-per evitare conflitti, 2-per evitare dannose dipendenze che possono farti perdere un sacco di tempo, e 3-per renderlo snello e "atomico" (quanto mi piace questa parola
).
In un .dll puoi mettere indifferentemente .cpp e .h, suppongo. Non ti so dire con precisione come poter fare con Visual C++, però a grandi linee Visual Studio dovrebbe essere abbastanza "standardizzato".
Un'altra cosa che non ho capito benissimo e la suddivisione del progetto in file.
Differente è la questione di più file nello stesso progetto.
Allora, vediamo.
Quella che si chiama "soluzione" comprende più progetti, siano essi eseguibili (.exe) o librerie dinamiche (.dll). Altri file li considero "accessori" (come file di configurazione, eccetera, che non sono strettamente necessari per il funzionamento dell'applicazione). Come ho accennato sopra, un progetto può essere sia "Windows form" (cioè un eseguibile con finestra, eccetera) che "Windows library" (la .dll abbinata al progetto).
Secondo me quello che è più difficile (e che dovrebbe essere tra le prime cose da imparare) è come "far pescare" le funzioni o le variabili condivise o con riferimento cosiddetto "ad oggetto" ad un determinato blocco, una determinata funzione, un determinato file, eccetera.
Nel caso di Visual Basic hai come base una cosa che si chiama "Namespace". Un namespace può essere diviso in diverse sezioni: moduli, classi, librerie... È un po' come parlare della root di un sistema UNIX.
Se non è dichiarato,
per default un namespace ha il nome della soluzione in cui sta.
Poi c'è un eventuale classe (considerando il caso più semplice), che può essere un form, e in una class può stare una funzione o una sub (parlando sempre di VB). Se in quella classe è dichiarata una variabile condivisa, per esempio, "a", per richiamarla da qualche altra parte dovrai chiamarla così:
namespace.class.a
Variabili condivise sono allo stesso livello di funzioni o sub. Se dichiari una variabile in una sub o in una funzione, prima di tutto se la metti "Shared" il compilatore ti dà errore, proprio perchè attributi "shared" devono stare direttamente all'interno di classi.
O meglio, all'esterno di metodi o procedure.Questo è un metodo che ricorda molto gli struct del C. Anzi, essenzialmente si basano sullo stesso principio: in un "blocco" ci sono degli elementi che, per essere usati esternamente, devono essere dichiarati sotto altro nome. Allora, se c'è una classe esterna in cui c'è una funzione di cui abbiamo bisogno dobbiamo fare:
Dim class1 As namespace.class
Dim arg1, arg2 As Integer
Dim arg3, arg4 As Double
Dim res1 As Integer = class1.func1(arg1, arg2)
Dim res2 As Double = class1.func2(arg3, arg4)
e magari nel namespace
namespace c'è una classe
class dove stanno queste due funzioni:
Public Shared Function func1(ByVal arg1 As Integer, ByVal arg2 As Integer) As Integer
Return arg1 * arg2
End Function
'---'
Public Shared Function func2(ByVal arg3 As Double, ByVal arg4 As Double) As Double
Return arg3 / arg4
End Function
Più o meno. Le cose si complicano quando devi richiamare funzioni da dll esterne. Se le dll -detta brutalmente- non sono API di sistema, si possono richiamare con Import.
Import class = namespace.class
o
Import class = namespace.module.class
dove
class a sinistra dell'uguale è l'alias con cui quella classe è conosciuta
all'interno del progetto.
namespace è il namespace in cui devi andare a prendere la classe;
module è un eventuale modulo e
class è la classe vera e propria in cui stanno le funzioni che ti servono. Allora da questo si evincono due cose:
1-Le funzioni esterne
non possono essere chiamate direttamente, c'è bisogno di un'
importazione come quella che ho appena descritto, o una
referenza ad oggetto, come quella che ho descritto più su.
2-
Ogni funzione che vuoi chiamare deve essere chiamata attraverso la rispettiva classe di appartenenza. Come un albero genealogico che devi percorrere, a meno che non usi Import. Allora la classe è conosciuta con un alias.
Alla fin fine devi "solo" fare molta attenzione agli attributi di funzione. Per esempio:
--Se la classe "class" è dichiarata come "Private" non c'è verso di richiamare le funzioni che ha all'interno. Deve avere attributo "Public".
--Se la funzione all'interno della classe è solo "Public" non può essere richiamata nemmeno con una referenza ad oggetto. Deve avere attributo "Public Shared" (come ho scritto sopra, se hai fatto caso
).
Infine, so che Visual Basic e Visual C++ hanno in comune molte cose. Più o meno dovresti trovare dichiarazioni analoghe in Visual C++.
Dimmi se ti ho confuso ancora di più le idee, o se ho diradato il miasma, almeno un pochino.
Ah, un'ultima cosa. Io per l'interfaccia uso .NET. Le API sono micidiali perchè 1-sono difficili da usare, come hai scoperto, e perchè 2-un minimo errore può avere conseguenze catastrofiche. Pensa alle API che controllano i dischi rigidi o la memoria RAM...
Uhm... potrei cominciare a scrivere qualche cosetta sul Visual Basic...