ho dichiarato un'importazione DLL nel mio programma C# che assomiglia a questo:funzione più chiamate da C# per C++ codice non gestito provoca AccessViolationException
[DllImport("C:\\c_keycode.dll", EntryPoint = "generateKeyCode",
CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr generateKeyCode(char[] serial, char[] option, char c_type);
Si fa riferimento alla funzione generateKeyCode()
interno del mio DLL.
Qui è il codice che sta causando un errore (punti di interruzione utilizzati):
const char* generateKeyCode(char serial[],
char option[],
char c_type)
{
returnBufferString = "";
SHA1_CTX context;
int optionLength = 0;
#ifdef WIN32
unsigned char buffer[16384] = {0};
#else
unsigned char buffer[256] = {0};
#endif
//char output[80];
char keycode[OPTION_KEY_LENGTH+1] = "";
int digest_array_size = 10; //default value for digest array size
unsigned char digest[20] = {0};
char optx[24] = {0};
char c_type_upper;
// Combine serial # and Option or Version number
char str1[30] = {0};
int i;
int size = 0;
int pos = 0;
...
...
}
Fondamentalmente, ho importato questa DLL in modo da poter passare i parametri di funzione e potrebbe fare il suo algoritmo e semplicemente mi restituire un risultato . Ho usato questa funzione di marshalling ...
public static string genKeyCode_marshal(string serial, string option, char type)
{
return Marshal.PtrToStringAnsi(generateKeyCode(serial.ToCharArray(),
option.ToCharArray(), type));
}
... così ho potuto effettuare correttamente la chiamata. All'interno del mio file di intestazione C++, ho definito una stringa, come indicato è utile nella risposta a questo question (è la variabile returnBufferString
presente nella parte superiore della funzione C/C++).
Faccio questa chiamata di funzione più volte mentre utilizzo un controllo NumericUpDown
per passare da 1,0 a 9,9 con incrementi di 0,1 (ciascuno verso l'alto o verso il basso accompagna un'altra chiamata di funzione), quindi di nuovo indietro. Tuttavia, ogni volta che provo a farlo, il programma si aggancia dopo un numero apparentemente impostato di chiamate di funzione (si ferma a 1,9 sulla via del ritorno se procedo semplicemente su e giù, o prima se mi alternano su e giù un po ') .
Si prega di notare che funziona e mi dà il valore che voglio, non ci sono discrepanze lì.
Ho cambiato la dimensione del buffer in un numero più piccolo (5012) e quando ho provato a eseguire il programma, alla prima chiamata di funzione ha gettato l'AccessViolationException. Tuttavia, raddoppiando la dimensione del buffer a due volte (32768) l'originale non ha avuto alcun effetto rispetto all'originale - salendo direttamente a 9,9 da 1,0 e in basso di nuovo, si ferma a 1,9 e genera l'eccezione.
MODIFICA: l'impostazione predefinita è ANSI, quindi ANSI. Nessun problema lì. È un problema di allocazione della memoria ??
Dopo ulteriori test, sembra che la funzione abbia problemi di memoria indipendentemente da quando o dove viene chiamata in quel momento, le mie stampe di debug mostrano che ci sono un sacco di valori spazzatura nello stream, e così genera la chiave sbagliata. Sento che questo è probabilmente correlato. –
Un carattere in C# è largo 2 byte. In C, char è solo 1 byte (penso che avresti bisogno di essere un wchar_t per essere 2 byte a seconda delle opzioni del compilatore). Vorrei iniziare da lì. –