Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - recv non bloccante con PInvoke
Forum - C# / VB.NET - recv non bloccante con PInvoke

Avatar
lorenzo (Normal User)
Guru


Messaggi: 1178
Iscritto: 15/04/2008

Segnala al moderatore
Postato alle 14:48
Domenica, 11/03/2012
Allora, ho riscontrato un comportamento strano richiamando da .NET una DLL scritta in C.

La firma del metodo invocato è questa:
Codice sorgente - presumibilmente C# / VB.NET

  1. tables_t * get_table(char *tableName, SOCKET *connection, tables_t *tbls, char *error);



mentre la firma tramite PInvoke è la seguente:
Codice sorgente - presumibilmente C# / VB.NET

  1. [System.Runtime.InteropServices.DllImportAttribute("MirageHPDB.dll", EntryPoint = "get_table")]
  2.         public static extern IntPtr get_table(IntPtr tableName,
  3.           IntPtr conn, IntPtr tbls, IntPtr errore);



Dal lato .NET, la chiamata avviene nel seguente modo:
Codice sorgente - presumibilmente C# / VB.NET

  1. try
  2.             {
  3.                 IntPtr host = Marshal.StringToHGlobalAnsi("127.0.0.1");
  4.                 IntPtr dbname = Marshal.StringToHGlobalAnsi("oasys");
  5.                 IntPtr tblname = Marshal.StringToHGlobalAnsi("variabili");
  6.                 int port = 33033;
  7.                 int error = 0;
  8.                 IntPtr errore = Marshal.AllocHGlobal(500);
  9.                 IntPtr dbconnect = NativeDLL.open_database(dbname, host, port, out error);
  10.                 NativeDLL.tables tbls = new NativeDLL.tables();
  11.                 IntPtr tblsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(tbls));
  12.                 Marshal.StructureToPtr(tbls, tblsPtr, false);
  13.                 Console.ReadKey();
  14.                 tblsPtr = NativeDLL.get_table(tblname, dbconnect, tblsPtr, errore);
  15.                
  16.                 Console.WriteLine(errore);
  17.                 Console.ReadKey();
  18.             }
  19.             catch (Exception ex)
  20.             {
  21.                 Console.WriteLine(ex.Message);
  22.                 Console.ReadKey();
  23.             }



in cui NativeDLL è una classe C# che contiene le firme Pinvoke dei metodi e la funzione open_database restituisce un puntatore a soket da passare alla get_table.



Il problema è il seguente: nel metodo get_table c'é una recv. Quando chiamo la DLL da un programma C nativo(tramite LoadLibrary) la recv rimane correttamente in attesa fino a quando il server non ha qualcosa da mandare.
Se richiamo la DLL da C# invece la recv smette di essere bloccante e ritorna sempre -1 con messaggio di errore: "operazione completata".

Perché la recv chiamata dal PInvoke diventa non bloccante?

NB: ho anche debuggato la parte .NET entrando nel codice della DLL(che ho scritto io) quindi ho verificato personalmente questo comportamento
NB2: vi anticipo anche che il puntatore SOCKET ritornato dalla open_database è corretto, perché nella get_table prima della recv ci sono alcune send che il server riceve in maniera corretta.

Ultima modifica effettuata da lorenzo il 11/03/2012 alle 14:55


"There's no point in being exact about something if you don't even know what you're talking about."

JOHN VON NEUMANN


Siamo italiani NO??
Allora scriviamo in ITALIANO!!!!
PM
Avatar
vankraster (Member)
Rookie


Messaggi: 32
Iscritto: 05/11/2010

Up
0
Down
V
Segnala al moderatore
Postato alle 23:55
Sabato, 31/03/2012
Ti suggerisco di leggere il seguente articolo da Microsoft:
http://msdn.microsoft.com/en-us/library/ms235282.aspx


Ci possono togliere tutto tranne la ragione e con questa possiamo ricostruire l'universo.
PM