Проблема с импортом DLL в Inno-Setup - PullRequest
1 голос
/ 23 августа 2010

Я импортирую C ++ DLL в скрипт установки innosetup. Код DLL выглядит следующим образом:

void __stdcall SetFbParam(char *dbFileName,char *dbTableName,char *dbParamName,char *dbParamValue){
//of no use here and doesn't change anything}

В Innosetup я импортирую его, используя

procedure FBset(dbFileName,dbTableName,dbParamName,dbParamValue: String;);

external 'SetFbParam@files:MyDll.dll stdcall setuponly';

Однако, я всегда получаю ошибку времени выполнения при запуске установщика, говоря, что он не может импортировать мою dll. Я пробовал это с различными соглашениями о вызовах, но это всегда терпит неудачу. Если это имеет какое-либо значение, я запускаю Win7 x64 с включенным UAC (установщик запрашивает повышение прав и после этого вылетает).

Точное сообщение:
Ошибка
Ошибка времени выполнения (при -1: 0):
Невозможно импортировать
dll: C: \ Users \ Nevod \ AppData \ Local \ Temp \ is-6LOEC.tmp \ MyDll.dll

DLL там.

Спасибо!

Ответы [ 3 ]

6 голосов
/ 27 августа 2010

Является ли MyDll.dll 32-разрядным?

Зависит ли MyDll.dll от любых других библиотек DLL в этом же каталоге?Если это так, вам нужно перечислить имена этих библиотек после «MyDll.dll», чтобы убедиться, что они извлекаются до загрузки MyDll.dll, и вам, вероятно, понадобится опция «loadwithalteredsearchpath» какЧто ж.Пример из справки :

procedure ADllFunc(hWnd: Integer; lpText, lpCaption: String; uType: Cardinal);
external 'ADllFunc@files:A.dll,B.dll stdcall loadwithalteredsearchpath'; //A.dll depends on B.dll
3 голосов
/ 14 ноября 2013

(я знаю, что оно старое, но, возможно, некоторые другие тоже обращаются к нему)

Скорее всего, имя функции искажено в C ++ DLL.У меня была такая же проблема, и я смог ее решить, перекомпилировав dll.Вкратце:

Если вы экспортируете из C ++ что-то вроде:

void __stdcall foo() 

, вы получите функцию с именем (Visual Studio):

?foo@@YGXXZ

Чтобы предотвратить искажение имениВы должны использовать экспортную директиву "C".Пример (Visual Studio)

extern "C" __declspec( dllexport ) void __stdcall foo()

Однако я обнаружил, что Visual Studio будет продолжать искажаться, и вы получите что-то вроде:

_foo@0

Единственный способ, которым я смог получить чистые именаобъясняется здесь: C ++ DLL Export: декорированные / искаженные имена

И виновник действительно __stdcall.Если вы удалите это из своего объявления:

extern "C" __declspec( dllexport ) void foo()

, вы снова получите чистый экспорт, даже без файла DEF.IMO, это должно быть достаточно хорошо, так как код выше объявляет экспортируемую функцию "C" и соглашение о вызовах по умолчанию для C - это stdcall.Однако у меня не было времени и возможности проверить это, поскольку добавить файл DEF намного проще, чем перемещаться по коду asm и проверять указатели стека:)

1 голос
/ 14 марта 2015

Чтобы использовать библиотеки DLL в разделе [Code] InnoSetup, убедитесь, что:

  • DLL работает в 32-разрядном режиме (даже если установщик построен для 64-разрядных систем и работает в 64-разрядных режимах)
  • экспортируемые функции имеют extern "C" __declspec( dllexport ) модификатор
  • , использующий соглашение о вызовах cdecl, поскольку stdcall искажает имя (http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx). Конечно, можно указать искаженное имя в операторе импорта InnoSetup. Но, похоже,проще просто использовать cdecl
...