
lorenzo (Normal User)
Guru
    
Messaggi: 1178
Iscritto: 15/04/2008
|
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 |
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 |
[System.Runtime.InteropServices.DllImportAttribute("MirageHPDB.dll", EntryPoint = "get_table")]
public static extern IntPtr get_table(IntPtr tableName,
IntPtr conn, IntPtr tbls, IntPtr errore);
|
Dal lato .NET, la chiamata avviene nel seguente modo:
Codice sorgente - presumibilmente C# / VB.NET |
try
{
IntPtr host = Marshal.StringToHGlobalAnsi("127.0.0.1");
IntPtr dbname = Marshal.StringToHGlobalAnsi("oasys");
IntPtr tblname = Marshal.StringToHGlobalAnsi("variabili");
int port = 33033;
int error = 0;
IntPtr errore = Marshal.AllocHGlobal(500);
IntPtr dbconnect = NativeDLL.open_database(dbname, host, port, out error);
NativeDLL.tables tbls = new NativeDLL.tables();
IntPtr tblsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(tbls));
Marshal.StructureToPtr(tbls, tblsPtr, false);
Console.ReadKey();
tblsPtr = NativeDLL.get_table(tblname, dbconnect, tblsPtr, errore);
Console.WriteLine(errore);
Console.ReadKey();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadKey();
}
|
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 |