Я создал свой собственный dll
который выставляет один полезный метод, а именно GenarateID
, Заголовочный файл выглядит примерно так:
#ifndef GENERATE_ID_H
#define GENERATE_ID_H
#include <windows.h>
#include <string>
#include <fstream>
#include <stdio.h>
#include "openssl/sha.h"
int __declspec(dllexport) GenerateID(const char* fileName, char* retVal);
// some additional helper methods declared here, but omitted for brevity
// ...
#endif // GENERATE_ID_H
Что делает этот метод?
Он считывает двоичный файл, переданный в качестве первого аргумента, получает некоторые данные, генерирует хеш этих данных SHA256 и возвращает его через второй аргумент. В случае успеха возвращаемое значение int равно 0, в противном случае это отрицательное значение. Здесь стоит упомянуть, что я использовал библиотеку OpesSSL для этих целей.
Теперь вот где начинается проблема. Как видно из названия, я не могу вызвать dll
из NSIS с помощью System::Call
, (Я создал простой тестовый исполняемый файл консоли, который без проблем вызывает библиотеку.)
Вот что я попробовал, основываясь на этот короткий учебник:
# copy the files
SetOutPath $INSTDIR
SetOverwrite on
File C:\Users\Strahinja\Desktop\CRX\testfile.zip # copy the binary
File C:\OpenSSL-Win32\libeay32.dll # copy OpenSSL library
File C:\Users\Strahinja\Desktop\CRX\IDGenerator\Release\IDGenerator.dll # copy my dll
# generate id
StrCpy $R0 "testfile.zip"StrCpy $R1 ${NSIS_MAX_STRLEN} ;assign memory to out parameter ?
StrCpy $R2 -1
#System::Call 'IDGenerator::GenerateID(t, t)i (r10, .r11).r12'
System::Call 'IDGenerator::GenerateID(t r10,t .r11)i.r12'
DetailPrint "File parameter: $R0"DetailPrint "Generated ID: $R1"DetailPrint "Return value: $R2"
NSIS говорит, что возвращаемое значение error
, Есть ли способ проверить в чем ошибка, а главное — правильно ли я это использую?
В качестве примечания: я пытался использовать exe
вместо dll
скопировать его так же, как dll
и вызывая его с помощью:
nsExec::ExecToStack '"myidgen.exe"'
Pop $R2
Pop $R1
Исполняемый файл здесь работает нормально, но я бы все же предпочел dll.
Я чувствую, что это может иметь отношение к соглашению о вызовах или dllexport
(поскольку он использует искажение имени, AFAIK)
Какие-либо предложения?
Ошибка обычно означает синтаксическую ошибку, но это также может означать сбой LoadLibrary или GetProcAddress. использование Зависимость Уокер проверить, имеет ли экспортируемая функция оформленное имя.
Возможно, вы захотите использовать файл DEF для экспорта функции.
Если вы используете EXTERN_C int __cdecl __declspec(dllexport) foo()
он также должен быть экспортирован без отделки, но тогда вам нужно добавить ?c
до конца системного вызова …
Других решений пока нет …