Я объявил импорт DLL в моей программе C#, который выглядит следующим образом:Множественные вызовы функций из C# в C++ неуправляемый код вызывает AccessViolationException
[DllImport("C:\\c_keycode.dll", EntryPoint = "generateKeyCode",
CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr generateKeyCode(char[] serial, char[] option, char c_type);
Он ссылается на функцию generateKeyCode()
внутри моей DLL.
Вот код, который вызывает ошибку (используемые точки останова):
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;
...
...
}
В принципе, я импортировал этот DLL, так что я мог бы передать параметры функции, и это может сделать его алгоритм и просто вернуть мне результат , Я использовал эту функцию маршалера ...
public static string genKeyCode_marshal(string serial, string option, char type)
{
return Marshal.PtrToStringAnsi(generateKeyCode(serial.ToCharArray(),
option.ToCharArray(), type));
}
... так что я мог правильно позвонить. Внутри моего заголовочного файла C++ я определил строку, как указано в ответе на этот вопрос question (это переменная returnBufferString
, присутствующая в верхней части функции C/C++).
Я вызываю эту функцию несколько раз, так как я использую элемент управления NumericUpDown
для перехода от 1.0 до 9.9 с шагом 0,1 (каждый вверх или вниз сопровождает другой вызов функции), а затем снова назад. Тем не менее, каждый раз, когда я пытаюсь это сделать, программа захватывается после кажущегося набора вызовов функций (останавливается на 1.9 на обратном пути, если я просто иду вверх и вниз, или раньше, если я чередую немного вверх и вниз) ,
Обратите внимание: это работает и дает мне значение, которое я хочу, там нет расхождений.
Я изменил размер буфера на какое-то меньшее число (5012), и когда я попытался запустить программу, при первом вызове функции это привело к исключению AccessViolationException. Однако удвоение размера буфера до двух (32768) оригинала не имело никакого эффекта по сравнению с оригиналом - вплоть до 9,9 от 1,0 и обратно назад, оно останавливается на 1,9 и выдает исключение.
EDIT: По умолчанию ANSI, поэтому ANSI. Проблем нет. Это проблема распределения памяти?
При дальнейшем тестировании кажется, что функция имеет проблемы с памятью независимо от того, когда или где она вызывается в этом время, мои отладочные распечатки показывают, что в потоке есть куча значений мусора, и поэтому генерирует неправильный ключ. Я чувствую, что это, вероятно, связано. –
Символ в C# имеет ширину 2 байта. В C char имеет только 1 байт (я думаю, вам нужно, чтобы wchar_t составлял 2 байта в зависимости от параметров компилятора). Я бы начал там. –