Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. 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
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

PM