Проверьте серийный ключ с помощью автономного файла DLL - функция преобразования NSIS = ›Prototype =› Pascal

Не могли бы вы помочь мне с созданием функции последовательной проверки, основанной на файле DLL? К сожалению, у меня нет прототипа функции.

У меня есть версия функции NSIS:

SetOutPath $PLUGINSDIR
  File "serialtest.dll"
   System::Call "serialtest::_sn_serialtest(t r1) i .r2 ?u"
  ${If} $2 == 0
   Messagebox MB_OK|MB_ICONSTOP \
    "Invalid Serial Number!"
   Abort
  ${Endif}

t - текст, строка (LPCSTR, указатель на первый символ)

r1-r9 - это от 1 до 9 долларов за NSIS (можно вводить или выводить). В этом случае r1 - это $ 1, а $ 1 - это серийный номер с разделителями "-".

i - int (включает char, byte, short, дескрипторы, указатели и т. Д.)

. - означает отсутствие ввода

u - выгрузить DLL

Дополнительная информация: NSIS Script написан на ANSI, и я использую Unicode-версию Inno Setup.

Если возможно, серийный номер следует импортировать из полей редактирования - я задал вопрос о настраиваемой последовательной странице здесь: CustomPage для серийного номера в Inno Setup


person RobeN    schedule 07.05.2012    source источник


Ответы (2)


Я вообще не знаю NSIS, поэтому это всего лишь попытка интерпретации скрипта:

serialtest::_sn_serialtest(t r1) i .r2 ?u

Я так понимаю:

serialtest.dll - это библиотека, в которую функция импортируется из
t - входной строки, набранной как LPCSTR
i - целочисленного результата помещается во входную переменную (т.е. просто выходную переменную)

Итак, ваш прототип мог бы выглядеть так:

int _sn_serialtest(
  __in LPCSTR sn
);

Что мне здесь не хватает, так это нотации соглашения о вызовах, поэтому следующий прототип может не работать, если вы знаете, что библиотека была написана на C (каковы большинство плагинов NSIS, как я искал в Google), то, вероятно, это cdecl, например ниже, но это только мое предположение, все может быть иначе:

function _sn_serialtest(sn: AnsiString): Integer;
  external '_sn_serialtest@files:serialtest.dll cdecl';
person TLama    schedule 07.05.2012
comment
Ага, похоже, эта функция работает! Я вызвал свои SerialEdits блоки в цикле, чтобы создать полную последовательную строку с разделителем '-', а затем вызвал _sn_serialtest функцию. Если результат 1, значит, серийный номер правильный - здесь мы можем воспользоваться функцией кнопки «Далее». - person RobeN; 07.05.2012

Другой ответ был принят до того, как я успел ответить, поэтому я просто добавлю дополнительную информацию:

В то время как плагины NSIS используют cdecl для своих экспортируемых функций, System :: Call по умолчанию является stdcall, поскольку он обычно используется для вызова WinAPI. (Для cdecl вам нужно ?c в конце)

Тип t зависит от версии NSIS, в обычной сборке это char*, а в сборке юникода - WCHAR* (t похоже на TCHAR, у вас также есть w и m для WCHAR и char).

Прототипом C для функции в вашем вопросе является int WINAPI _sn_serialtest(LPCTSTR);, а в вашем случае LPCTSTR = LPCSTR и WINAPI = __stdcall.

person Anders    schedule 07.05.2012
comment
Тот факт, что функция имеет префикс подчеркивания, заставляет меня подозревать, что функция действительно cdecl и что системный плагин все еще может как-то ее вызывать (вероятно, он играет со стеком трюки, поэтому не имеет значения, что вы повредили стек на возвращение) - person Anders; 07.05.2012
comment
Это cdecl, как и stdcall Я получаю нарушение прав доступа. cdecl с String вместо AnsiString приводит к тому, что проверка всегда дает отрицательный результат. Но именно поэтому я указал, что у меня есть ANSI NSIS и UNICODE Inno Setup. В этом случае решение TLama работает отлично :-) - person RobeN; 07.05.2012
comment
Затем, если вы собираетесь продолжать использовать NSIS, вам следует изменить? U на? Uc. - person Anders; 07.05.2012