Logo UGIdotNET

Discussione 'P/INVOKE'

# Pubblicato il 19 mar 2003 12.04 - Rispondi
Ste Dev
P/INVOKE
Sto cercando di interoperare con una DLL win32 che implementava un protocollo proprietario di comunicazione seriale.
Ho creato la seguente interfaccia:
interface IProtocolloBase
{
bool Connetti(int com, int baudRate, char parity, int dataBit, int stopBit,
int veicolo, int dispositivo, uint nTraceTime);
void Sconnetti();
bool ScritturaRandom(Int32[] pdwAddresses, char[] pchBuffer,
uint size, uint sizeOfBasicType);
bool Reset();
}
Ho definito poi una classe che implemeta questa interfaccia:
public class Protocollo98 : IDisposable, IProtocolloBase
{
#region Win32API
[DllImport("serprt98.dll")]
public static extern bool SPConnect(int COM, int baudRate, char parity, int dataBit, int stopBit, int veicolo, int dispositivo, uint traceTime);
[DllImport("serprt98.dll")]
public static extern void SPDisconnect();
// questo è il prototipo scritto in Visual C++
// BOOL SPWriteRandom(LPDWORD pdwAddresses, LPCSTR pchBuffer,
// UINT nSize, UINT nSizeofBasicType)
[DllImport("serprt98.dll")]
public static extern bool SPWriteRandom(Int32[] pdwAddresses, char[] pchBuffer, uint size, uint sizeOfBasicType);
[DllImport("serprt98.dll")]
public static extern bool SPResetCPU();
#endregion

public Protocollo98()
{
}

~Protocollo98()
{
Dispose(false);
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(disposing)
{
// vengono liberate le risorse relative ai managed objects
}
// vengono liberate le risorse relative agli unmanaged objects
Sconnetti();
}
public bool Connetti(int com, int baudRate, char parity, int dataBit, int stopBit,
int veicolo, int dispositivo, uint traceTime)
{
return SPConnect(com, baudRate, parity, dataBit, stopBit, veicolo,
dispositivo, traceTime);
}
public void Sconnetti()
{
SPDisconnect();
}
public bool ScritturaRandom(Int32[] pdwAddresses, char[] pchBuffer,
uint size, uint sizeOfBasicType)
{
return SPWriteRandom(pdwAddresses, pchBuffer, size, sizeOfBasicType);
}
public bool Reset()
{
return SPResetCPU();
}
}
Chi mi da un occhio se ho implentato correttamente i wrapper ? Sopratutto quello chiamato ScritturaRandom che in Visual C++ lo avevo scritto così;
BOOL SPWriteRandom(LPDWORD pdwAddresses, LPCSTR pchBuffer,
UINT nSize, UINT nSizeofBasicType)
pdwAddresses memorizzava un array di indirizzi di variabili che andavo a crivere via seriale.
pchBuffer era un buffer di unsigned char che conteneva i valori da spedire via seriali associati agli indirizzi precedenti.
GRAZIE
# Pubblicato il 20 mar 2003 23.08 - Rispondi
Raffaele Rialdi
Re: P/INVOKE
> // questo è il prototipo scritto in Visual C++
> // BOOL SPWriteRandom(LPDWORD pdwAddresses, LPCSTR pchBuffer,
> // UINT nSize, UINT nSizeofBasicType)
> [DllImport("serprt98.dll")]
> public static extern bool SPWriteRandom(Int32[] pdwAddresses, char[] pchBuffer,
> uint size, uint sizeOfBasicType);

A occhio direi:
[DllImport("serprt98.dll", CharSet=CharSet.Auto)]
public static extern bool SPWriteRandom(ref uint pdwAddresses, [in,out] StringBuilder pchBuffer, uint size, uint sizeOfBasicType);

LPDWORD è un puntatore ad una dword e quindi un ref ad un uint.
LPCSTR può essere string se è solo in ricezione ma se è anche in uscita deve essere uno StringBuilder perchè il buffer interno della string è immutabile.
il resto è ok.

C'è una bella tabella in msdn nell'articolo "Platform Invocation Services"

Raffaele
# Pubblicato il 21 mar 2003 8.36 - Rispondi
Ste Dev
Re: P/INVOKE
Grazie 1000 Raffaele,
per passare alla mia DLL un array di indirizzi mi hai suggerito
ref uint :pdwAddresses
In questo modo riesco a spedire alla mia DLL più indirizzi del tipo:
0x00000001
0x00000002
.....
Ho un dubbio su StringBuilder pchBuffer quello che dovrei utlizzare per spedire alla mia dll un array di valori:
a me servirebbe spedire un array di unsigned char. Posso utilizzare la StringBuilder per questo scopo ?
Grazie per il chiarimento.
# Pubblicato il 21 mar 2003 21.35 - Rispondi
Raffaele Rialdi
Re: P/INVOKE
> In questo modo riesco a spedire alla mia DLL più indirizzi del tipo:
> 0x00000001
> 0x00000002
Non avavo capito che ce ne fossero molti. Se ce n'è più di uno probabilmente non ti funziona
Ma con quale parametro sai quanti indirizzi ci sono nell'array? Potrebbe essere necessario usare "MarshalAs" (guarda msdn perchè la questione è più complessa) .net infatti deve riuscire a capire quanto è lungo l'array.

> Ho un dubbio su StringBuilder pchBuffer quello che dovrei utlizzare per spedire alla mia
> dll un array di valori:
> a me servirebbe spedire un array di unsigned char. Posso utilizzare la StringBuilder per
> questo scopo ?
> Grazie per il chiarimento.
Si, dopo tutto una stringa è un array di byte che terminano con null. Il vantaggio di trattarli come stringa viene dal fatto che sai già come capire dove finisce l'array.

Raffaele
# Pubblicato il 24 mar 2003 7.55 - Rispondi
Ste Dev
Re: P/INVOKE
Ricordi il prototipo della mia funzione:
public static extern bool SPWriteRandom(Int32[] pdwAddresses, char[] pchBuffer,
uint size, uint sizeOfBasicType);
Il parametro SIZE mi determina quanto è lungo l'array pwdAddress.
Hai qualche idea ? Devo usare MarshasAs ?

# Pubblicato il 24 mar 2003 8.21 - Rispondi
Corrado Cavalli
Re: P/INVOKE
Visto che la DLL riceve l'indirizzo di memoria di partenza dell'array ha bisogno ovviamente di conoscere la lunghezza quindi basta che passi semplicemente il numero di elementi contenuti,non e' necessario MarshalAs

HTH
Corrado
# Pubblicato il 24 mar 2003 8.31 - Rispondi
Ste Dev
Re: P/INVOKE
Ti ringrazio per la risposta ora mi mettero un po a studiare l'interoperablilità ! Ma giusto per avere un'idea: quando o meglio in quali situazione uso MarshalAs ?
# Pubblicato il 24 mar 2003 8.42 - Rispondi
Raffaele Rialdi
Re: P/INVOKE
Concordo con Corrado se l'array è di lunghezza fissa.
Se è invece di lunghezza variabile (così mi sembrava) devi usare MarshalAs, specificando la proprietà SizeParamIndex che dice qual'è il parametro della funzione che indica la lunghezza dell'array (nel tuo caso size).

MarshalAs permette inoltre di specificare manualmente la mappatura tra il tipo nativo (win32) e il tipo .net quando la mappatura automatica non è soddisfacente. (Su msdn ci sono un po' di esempi).

Raffaele
# Pubblicato il 24 mar 2003 8.47 - Rispondi
Corrado Cavalli
Re: P/INVOKE
Quando devi dettagliare al condice unmanaged come trattare il parametro che gli passi, in particolar modo quando il parametro puo' essere passato in modi diversi (vedi ad esempio le stringhe che possono essere passate sia ANSI che UNICODE)
MarshalAs e' anche necessario quando devi passare una struttura che ha dei fields di tipo stringa a lunghezza fissa.

HTH
Corrado
# Pubblicato il 24 mar 2003 8.54 - Rispondi
Ste Dev
Re: P/INVOKE
GRAZIE 1000.
Scusa non c'entra nulla, al forum dell'11 marzo ho visto Andrea usare Visio per rappresentare gli oggetti del sito UGI. Io ho due versioni di Visio: Visio 2002 professional e Visio for Enterprise Architect. Mi chiedo qual'è piu appropriato installare ? Quale usava Andrea durante il suo intervento ?
GRAZIE e scusa per questo FUORI ARGOMENTO
# Pubblicato il 24 mar 2003 9.07 - Rispondi
Corrado Cavalli
Re: P/INVOKE
Credo che la persona piu adatta per rispondere sia Andrea, comunque se ben ricordo Visio EE e' qualla che si integra direttamente in VS quindi forse la piu' adatta.

Corrado
# Pubblicato il 24 mar 2003 16.30 - Rispondi
Andrea Saltarello
Re: P/INVOKE
> Quale usava Andrea durante il suo intervento ?
Ciao "Ste"... Come ti ha giustamente detto Corrado, stavo usando la ver "Enterprise Architect"

> GRAZIE e scusa per questo FUORI ARGOMENTO
prego :-)

.A
# Pubblicato il 24 mar 2003 16.36 - Rispondi
Ste Dev
Re: P/INVOKE
Impossibile chiederti una bozza del documento Visio che hai fatto vedere durante l'incontro dell'11 marzo che mi sembra riguardava proprio il sito UGI ?
# Pubblicato il 26 mar 2003 0.01 - Rispondi
Andrea Saltarello
Re: P/INVOKE
hai posta...

.A
# Pubblicato il 26 mar 2003 8.05 - Rispondi
Ste Dev
Re: P/INVOKE (x Andrea S.)
Ti rigrazio
vmister@tiscali.it. Infatti mi piacerebbe vedere come avevi progettato ad alto livello le classi astratte TemplateContenuto e TemplateContenutoCategorizzato ! Un po di design del software fa bene ogni tanto !!!
Ciao e grazie 1000

© 2001 User Group Italiano UGIdotNET. Tutti i diritti riservati. Note legali. - Partita IVA 01927050185