I am calling a simple Delphi dll from IA6. Can anyone shed some light on why the value of the var param passed to this function isn't changed when it's returned to the installation code? (If I put debug code into the dll method it all seems to be working fine, and the var param is populated as it should be.)
dll code:
procedure GetDecryptedPassword(aEncrypted: PChar; var aDecrypted: PChar); stdcall;
var
Cipher: TCipher;
Decrypted: string;
begin
Cipher := TCipher.Create;
try
Decrypted := Cipher.DecryptedString(cDBKey, string(aEncrypted));
StrLCopy(aDecrypted, PChar(Decrypted), Length(Decrypted) + 1);
finally
Cipher.Free;
end;
end;
IA code:
~InstallAware Clipboard Data~
~Call DLL Function~
~{A67FBE45-E960-42CA-AFE0-E225496F1530}~
~$SUPPORTDIR$\\InstSupt.dll,GetDecryptedPassword,void,,"pointer to string",$ENCPASSWORD$,"allocated string buffer (MAX_PATH length)",$UNENCPASSWORD$,$~
~mIDEFunc.dll\\mEXEFunc.dll~
After which $UNENCPASSWORD$ is the empty string it was initialised to, rather than the value aDecrypted was set to in the dll.
dll string parameter
-
- Site Admin
- Posts: 364
- Joined: Mon Jul 30, 2007 11:51 am
- Location: USA
- Contact:
This is a guess, but the problem may be that you are using allocated string buffer for $ENCPASSWORD$, instead of pointer to string. Your dll code requires both arguments to be of the same type. Try it by changing the type
Alejandro Ronquillo
InstallAware
Home of The Next Generation MSI Installer
Get your free copy today - http://www.installaware.com/
InstallAware
Home of The Next Generation MSI Installer
Get your free copy today - http://www.installaware.com/
-
- Posts: 15
- Joined: Tue Sep 05, 2006 6:40 am
- Location: UK
Thanks Alex. I've tried your suggestion, but it doesn't work (it's also at odds with all the relevant advice given in this forum). I've also tried using a char array as the parameter, to no avail. I've also tried using an 'out' parameter instead of a var. In all cases the dll procedure is called, it does what it should, and sets the value of the out/var parameter correctly. Back in the IA script, the value is always an empty string.
There are quite a few questions about this in the forum, and I can't see anywhere that anyone says they've succeded in getting string values back from a dll call. Is it the case that this just doesn't work, and I should stop wasting time and take a different approach, or has anyone actually succeded in doing this?
There are quite a few questions about this in the forum, and I can't see anywhere that anyone says they've succeded in getting string values back from a dll call. Is it the case that this just doesn't work, and I should stop wasting time and take a different approach, or has anyone actually succeded in doing this?
Dan
-
- Posts: 15
- Joined: Tue Sep 05, 2006 6:40 am
- Location: UK
I gave up on this - wasted too much time on a trivial problem when there are real problems waiting to be fixed. My workaround was to have the dll write the value to a file and then have IA read the values out of the file (actually a list of key-value pairs which are then read in as an ini file).
It's awful, and I hate doing hacks like that and then hoping for the best when it gets released, but I couldn't see another way round it, and IA weren't being much help, as you can see! (A simple "sorry, it doesn't work" would have at least saved valuable time).
It's awful, and I hate doing hacks like that and then hoping for the best when it gets released, but I couldn't see another way round it, and IA weren't being much help, as you can see! (A simple "sorry, it doesn't work" would have at least saved valuable time).
Dan
I've succeded actualy...
I return Exception.ToString() to the user.
c++ '/clr' code:
If I understand correct, TCHAR* (or char*) in c++ is like PChar in Delphi.
'var' param isn't changed because "Call Dll Function" holds pointer to that "allocated buffer" and copies it to the IA variable at the end of the function call. So, if you alter the pointer itself, ( in c++ simply by typing resultString = "something"; in Delphi, by using 'var') it will not return to the IA.
Realy, I don't know, how 'Call Dll Function' works. It just an assumption. But it works.
Code: Select all
~InstallAware Clipboard Data~
~Call DLL Function~
~{2AFB2974-B6D6-4C0F-8264-DD06A94DCB33}~
~BLABLABLABLABLA......"pointer to string",$CREDENTIALS_USERNAME$,"pointer to string",$CREDENTIALS_PASSWORD$,"allocated string buffer (MAX_PATH length)",$CREDENTIALS_ERROR$,$~
~mIDEFunc.dll\\mEXEFunc.dll~
I return Exception.ToString() to the user.
c++ '/clr' code:
Code: Select all
extern "C" __declspec(dllexport) int __stdcall ValidateUser(
//blablabla...
const LPCTSTR username,
const LPCTSTR password,
TCHAR* error)
{
// ...work...
// ...at some point
ExceptionToPStr(ex, error);
return something;
}
void ExceptionToPStr(Exception^ ex, TCHAR* str)
{
...
_tcsncpy(str, MYMESSAGE, _tcslen(str));
...
}
If I understand correct, TCHAR* (or char*) in c++ is like PChar in Delphi.
'var' param isn't changed because "Call Dll Function" holds pointer to that "allocated buffer" and copies it to the IA variable at the end of the function call. So, if you alter the pointer itself, ( in c++ simply by typing resultString = "something"; in Delphi, by using 'var') it will not return to the IA.
Realy, I don't know, how 'Call Dll Function' works. It just an assumption. But it works.
restriction
Only restriction on buffer (which is not cool) is MAX_PATH... for me it's 260 bytes.
Re: dll string parameter
For those that use Delphi instead of C++, here is how you make it work:
Delphi code (a complete working DLL with a single entry point):
IA Code (complete working MSIcode snippet):
Clear Text:
Clipboard data:
Enjoy!
Bond
Delphi code (a complete working DLL with a single entry point):
Code: Select all
library MySetupHelper;
uses
SysUtils, Classes, Windows;
{$R *.res}
function MyFunc (someINParam : PAnsiChar; someOUTParam : PAnsiChar; ) LongInt; stdcall;
var
MyINValue : String;
MyOUTValue : String;
begin
result := 1; //success
try
MyINValue := String(someINParam);
//Do some work here to get this value.
MyOUTValue := ''; //Set this value as needed.
StrPCopy(someOUTParam, MyOUTValue);
except on E:Exception do
result := 0; //failure
end;
end;
exports
MyFunc;
begin
end.
IA Code (complete working MSIcode snippet):
Clear Text:
Code: Select all
Set Variable SETUPHELPERFOLDER to
Set Variable DLLRESULT to
Set Variable INPARAM to MyINPARAMValue
Set Variable OUTPARAM to
Comment: Change souce path/file to be functional.
Define File Bag : C:\Temp\SetupHelper.dll, get runtime location of files into variable SETUPHELPERFOLDER
Call DLL Function $SETUPHELPERFOLDER$SetupHelper.dll->MyFunc (get result into variable DLLRESULT)
if Variable DLLRESULT Equals 1
MessageBox: DEBUG, OUTPARAM = $OUTPARAM$
else
MessageBox: DEBUG, DLLRESULT = $DLLRESULT$
end
Clipboard data:
Code: Select all
~InstallAware Clipboard Data~
~Comment~
~{DACF0133-0443-47A1-AECE-88B59B6EF4A2}~
~~
~End~
~{EADA86B3-2658-43A4-96CE-3DB310E4DAA7}~
~MessageBox~
~{23D3BA1B-97BE-4DC4-941A-5E7B1365491E}~
~DEBUG~
~DLLRESULT = $DLLRESULT$~
~0~
~1~
~~
~Else~
~{62D63A2A-E5E6-49D1-B240-3526BBF1FEF5}~
~MessageBox~
~{725BCCC7-9081-4716-9589-75977F094A5B}~
~DEBUG~
~OUTPARAM = $OUTPARAM$~
~0~
~1~
~~
~If~
~{C674B806-8257-4259-BB49-C6365CD5CE9C}~
~DLLRESULT~
~0~
~1~
~FALSE~
~Call DLL Function~
~{0D03DF5D-90FB-48B7-9C2B-4BA193425E24}~
~$SETUPHELPERFOLDER$SetupHelper.dll,MyFunc,long,DLLRESULT,"pointer to string",$INPARAM$,"allocated string buffer (MAX_PATH length)",$OUTPARAM$,$~
~mIDEFunc.dll\mEXEFunc.dll~
~File Bag~
~{0A9F82F2-BA63-49D9-9A48-36092BF72B4C}~
~C:\Temp\SetupHelper.dll|,FALSE,SETUPHELPERFOLDER~
~mFileBagIDE.dll\mFileBagEXE.dll~
~Comment~
~{53F00B30-6B60-4CAF-8651-C5DEFF895F60}~
~Change souce path/file to be functional.~
~Comment~
~{31A7C41B-0C01-4FD2-B8B0-3F759E0287B9}~
~~
~Set Variable~
~{B75A3126-8D18-420A-AE52-BAED9ACCC822}~
~OUTPARAM$MYAH$MYAH$FALSE~
~~
~Set Variable~
~{BC12E82F-4740-4A97-BC27-9377655A121F}~
~INPARAM$MYAH$MYAH$FALSE~
~MyINPARAMValue~
~Set Variable~
~{8E6ED04F-BF4E-4499-862D-84540F40A59B}~
~DLLRESULT$MYAH$MYAH$FALSE~
~~
~Set Variable~
~{0813AAF0-B614-4BD0-9E75-06DA1E5DBB15}~
~SETUPHELPERFOLDER$MYAH$MYAH$FALSE~
~~
Enjoy!
Bond
-
- Site Admin
- Posts: 5361
- Joined: Sun Aug 22, 2010 4:28 am
Re: dll string parameter
Thanks for sharing it!
Francesco Toscano
InstallAware Software
White Papers (HowTos) - http://www.installaware.com/publication ... papers.htm
Publications - http://www.installaware.com/publications-review.htm
InstallAware Help -F1 anywhere in the InstallAware IDE
InstallAware Software
White Papers (HowTos) - http://www.installaware.com/publication ... papers.htm
Publications - http://www.installaware.com/publications-review.htm
InstallAware Help -F1 anywhere in the InstallAware IDE
Who is online
Users browsing this forum: No registered users and 84 guests