Newsgroup: it.comp.lang.c++
Titolo: Matrice di interi come argomento di funzione

Il mio problema è questo: devo fare una DLL di funzioni che lavorano
su una matrice NxN di interi, ove N è determinato dal programma
chiamante.
Ho scritto una semplice funzione di prova  nella cui dichiarazione il
parametro che indica la matrice è definito come int* Array[]. Il
compilatore ha compilato senza errori, il problema è che non capisco
come passare il parametro da una funzione chiamante.
Non so se sono stata chiara ...

Non molto...
forse intendi che devi definire
int Matrice[m][n];
e poi chiamare la tua funzione come
funzioneNellaDll(Matrice) ?
forse che devi dichiarare la funzione dllexport?
non riesci a chiamare la funzione per niente?
hai provato dichiarando il parametro come int** ?


Infatti, non sono stata molto chiara.
Devo fare una DLL in C++ da usare con VB script. La dichiarazione
della funzione in VB e la chiamata le so fare (ho fatto una prova con
una semplice funzione che calcola il quadrato di un intero). Quello
che non riesco a fare è passare la matrice NxN (già dimensionata e
popolata dal programma chiamante in VB) alla funzione C. Dici che
definiendo il parametro come int** dovrebbe funzionare?
Nabira

 una semplice funzione che calcola il quadrato di un intero). 
la "prova" che hai fatto è relativa a una sola variabile, e non 
a una matrice. Se magari postassi il codice con cui dichiari la 
sub/function e, soprattutto, con che argomenti la chiami 
(modalità passaggio parametri), magari si capirebbe qualcosa di 
più del problema.
Per il resto hai già considerato ogni altra grana possibile, 
tipo diverse convenzioni di chiamata (passaggio parametri in 
ordine di dichiarazione o inverso, chi pulisce lo stack, se il 
chiamante o il chiamato, mangling dei normi, "visiblità" dei 
normi fuori dalla DLL e tutto, immagino).
C'era stato un thread un po' di tempo fa, a cui avevo 
partecipato pure io (all'epoca avevo fatto una dielleellina per 
confronto files, che appunto passava matrici di stringhe, da VB, 
non VBscript, a VC++, e viceversa, c'era anche una callback di 
notifica dello stato di avanzamento del lavoro con cui la 
funzione DLL comunicava al chiamante quanto lavoro aveva fatto).
Però non ricordo il titolo.
Prova a cercare fulltext, se si riesce, cercando SafeArray, OLE2 
o porcherie del genere (:-))
ciao
Soviet


 - Mostra testo tra virgolette -
// ********** Codice C *** INIZIO ***********************************
extern "C" __declspec (dllexport) int __stdcall Matrice(int** Array[],
int riga, int colonna)
{
	int risultato;
	risultato = *Array[riga][colonna];
	return risultato;
}
// ********** Codice C *** FINE ***********************************
// ********** Dichiarazione funzione in VB *** INIZIO
***********************************
Public Declare Function Matrice lib "ProveVettore.dll" Alias
"_Matrice@12"(ByRef Array as integer, r as integer, c as integer) as
integer
// ********** Dichiarazione funzione in VB *** FINE
***********************************
// ********** Codice VB *** INIZIO ***********************************
Dim MatAd(1,1) As Integer
dim test as integer
MatAd(0,0) = 11
matAd(0,1) = 12
MatAd(1,0) = 21
matAd(1,1) = 22
test = Matrice(MatAd(0,0),1,1)
// ********** Codice VB *** FINE ***********************************
Risultato: non funziona, si genera un "Unknown error".
I miei dubbi sono:
1) La funzione in C è sbagliata (non avevo mai usato i vettori
bidimensionali in C)
2) La dichiarazione della funzione in VB non è corretta
Cosa può essere?
ciao
Nabira

 2) La dichiarazione della funzione in VB non è corretta
sembra corretta. Rettifica prima la routine in C. Poi dopo, se 
ancora non funge, prova la chiamata con VarPtr esplicito
ciao
Soviet


definiendo il parametro come int** dovrebbe funzionare?
Non se hai scritto il parametro della funzione in quel modo.
Bada che int **mat è compatibile con int *mat[n], non con int
mat[m][n].

Nabira
Beh , a quanto pare gli altri hanno già risposto al posto mio, inoltre io 
non capisco un acca di VB per cui...
ad ogni modo il codice C dovrebbe essere:
extern "C" __declspec (dllexport) int __stdcall Matrice(int** Array,
int riga, int colonna)
{
int risultato = Array[riga][colonna];
    return risultato;
}

 - Mostra testo tra virgolette -
Posto che il codice C sia corretto, se invece che chiamarla da VB la
funzione la chiamassi da C, come dovrei passare il parametro?

 funzione la chiamassi da C, come dovrei passare il parametro?
es:
int Array[5][5];
Matrice(Array,0 ,0);
con questa chiamata chiedi alla funzione "Matrice" di processare il valore 
nell'angolo in alto a sinistra della matrice "Array".

nell'angolo in alto a sinistra della matrice "Array".
Se Matrice è una funzione che ha il prototipo seguente:
void Matrice(int **Array) 
Allora il codice che hai scritto NON è corretto e il motivo è spiegato
nell'altro mio messaggio in questo stesso thread.

 nell'altro mio messaggio in questo stesso thread.
giusto.
Nabira, se vuoi usare un array definito come
int Array[5][5]
devi usare la stessa definizione anche nella funzione
extern "C" __declspec (dllexport) int __stdcall Matrice(int Array[5][5], int 
riga, int colonna)
altrimenti puoi allocare dinamicamente la matrice e nella definizione della 
funzione puņ restare int**Array

 devi usare la stessa definizione anche nella funzione
Non necessariamente (vedi altro mio messaggio).

On 11 Apr, 21:48, Andrea Laforgia
<a.lafor...@andrealaforgia.it.invalid> wrote:

Azzeriamo tutto. Qualcuno ha voglia di mandarmi un esempio in C con:
1) Funzione 1  (di gestione della matrice) che ha come parametro un
puntatore ad una matrice bidimensionale.
2) Funzione 2 che chiama la 1 passandole la matrice dimensionata e
valorizzata.
Ricordo che il mio problema principale è che la dimensione della
matrice (quadrata) non è nota a priori dalla funzione di gestione.
Probabilmente, a furia di programmare con VB, mi sono dimenticata
totalmente i santi precetti del C e non riesco a far funzionare più
niente.
Comunque grazie a tutti
Nabira

 valorizzata.
Una cosa del genere potrebbe andare bene?
#include <iostream>
#include <iomanip>
void Riempi( int *PMatrice, int Size )
{
    for ( int i = 0; i < Size; ++i )
        for ( int j = 0; j < Size; ++j )
            PMatrice[ i * Size + j ] = ( i + 1 ) * ( j + 1 );
}
void Stampa( int *PMatrice, int Size )
{
    for ( int i = 0; i < Size; ++i )
    {
        for ( int j = 0; j < Size; ++j )
            std::cout << std::setw( 3 ) << PMatrice[ i * Size + j ] << ' ';
        std::cout << '\n';
    }
}
#define SIZE 10
int main()
{
    int Matrice[ SIZE ][ SIZE ];
    Riempi( &Matrice[ 0 ][ 0 ], SIZE );
    Stampa( &Matrice[ 0 ][ 0 ], SIZE );
    return 0;
}
Magari incapsulando il meccanismo in una classe. Oppure utilizzando 
direttamente un vector.
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg
The EMG Music page:         
http://www.emagsoftware.it/emgmusic
 

 ha scritto nel messaggionews:1176459709.6...@y80g2000hsf.googlegroups.com...

Ok, così ha funzionato ... in C; ma purtroppo la stessa funzione
invocata da VB continua a darmi errore (access violation).
Non so più che pesci pigliare.

matrice (quadrata) non è nota a priori dalla funzione di gestione.
Se non è nota a priori, allora quello che la tua funzione accetterà è
un parametro del tipo:
int **p;
E questo, ad essere precisi, *non* corrisponde al concetto di
"matrice". Una matrice implica la conoscenza delle dimensioni.
Quindi il prototipo sarà qualcosa del tipo:
void tuaFunzione(int **p, int rowCount, int colCount);
e chi avrà invocato tuaFunzione() si sarà preoccupato di allocare
memoria, per esempio in questo modo:
int **p;
p = (int**)malloc(rowCount * sizeof(int*));
for (int rowIndex=0; rowIndex!=rowCount; rowIndex++) {
  p[rowIndex] = (int*)malloc(colCount * sizeof(int));
  for (int colIndex=0; colIndex!=colCount; colIndex++) {
      p[rowIndex][colIndex] = 0;
  }
}
...
tuaFunzione(p, rowCount, colCount);
HTH
p.s: ho scritto senza compilare, spero di non aver sbagliato nulla ;)

On 13 Apr, 20:28, Andrea Laforgia
<a.lafor...@andrealaforgia.it.invalid> wrote:

Grazie a tutti per la collaborazione. Purtroppo però il problema non
dipende "solamente" dalla definizione della funzione C, ma
dall'applicativo con cui lavoro, che usa VB Script ma NON E' Visual
Basic.
Sono un po' demoralizzata ... il motivo di tutto questo è che ho
ideato un algoritmo di cui non vorrei rendere pubblico il sorgente e
per questo pensavo di utilizzare una DLL che eseguiva i calcoli e
restituiva il risultato al programma chiamante ...
CIAO

Basic.
Ti dň un consiglio: se ti č piů semplice, puoi pensare di passare i
dati tra i due sistemi usando delle stringhe. La matrice potrebbe
benissimo essere una stringa unica:
5 3 2
1 2 3
4 5 6
diventerebbe (antepongo le dimensioni):
"3 3 5 3 2 1 2 3 4 5 6"
Nel canale VBScript <--> C dovresti agevolmente riuscire a passare
almeno una stringa; come risultato dell'operazione, puoi fornire una
nuova stringa.

 per questo pensavo di utilizzare una DLL 
qui, scusa, non voglio essere caustico, ma i casi sono due, se 
l'algoritmo è realmente tosto, questa forma di "protezione" non 
è molto efficace perché funge solo con persone di scarsa 
pericolosità informatica, non contro veri pirati. Uno che lavora 
con un debugger serio ti disassembla la DLL e in qualche giorno 
non escludere che ti trascriva il tuo codice interpretando 
l'assembly. Non puoi contare troppo sul fatto di non includere 
le info di debug. Se uno ci lavora e ci vive di queste cose, se 
lo sgranocchia ugualmente anche compilato. Poi, per carità, è 
solo un'opinione. Eventualmente dovresti magari pensare a 
qualche ulteriore trucco di oscuramento del codice. Ci sono pure 
programmi appositi, ma non ne conosco nessuno.
Ah si .... il secondo caso è che l'algoritmo non sia proprio una 
bomba, e allora vai tranquilla anche col sorgente in chiaro :-)
P.S. Se VbScript fa schifino (io non lo so, mai usato) e 
immagino lo vuoi usare per il supporto offerto da vari browser, 
perché non provi con java (che pure quello come diffusione è 
mica male) ? Dovrebbe essere più semplice far interagire pezzi 
java e C che non VbScript e C. Non lo so per certo, eh, è solo 
un'idea dal fatto che Java assomiglia di più al C come sintassi. 
Chiedo scusa ai conoscitori del Java se ho scritto una bestialità
ciao
Soviet_Mario


Chiedo scusa ai conoscitori del Java se ho scritto una bestialità
La somiglianza tra linguaggi non è ragione sufficiente a renderli
facilmente integrabili, anche perché la capacità di integrazione
dipende dalle implementazioni. Non credo sia una buona alternativa.
p.s.: l'off-topic continua a espandersi.