dll string parameter

Got a problem you cannot solve? Try here.
Dan Fisher
Posts: 15
Joined: Tue Sep 05, 2006 6:40 am
Location: UK

dll string parameter

Postby Dan Fisher » Wed Sep 26, 2007 6:08 am

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.
Dan

Alex_Ronquillo
Site Admin
Posts: 364
Joined: Mon Jul 30, 2007 11:51 am
Location: USA
Contact:

Postby Alex_Ronquillo » Wed Sep 26, 2007 4:53 pm

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/

Dan Fisher
Posts: 15
Joined: Tue Sep 05, 2006 6:40 am
Location: UK

Postby Dan Fisher » Fri Sep 28, 2007 8:12 am

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?
Dan

elecuyer
Posts: 13
Joined: Thu Jun 28, 2007 9:47 am
Location: Haverhill, MA
Contact:

Postby elecuyer » Mon Dec 03, 2007 3:36 pm

I'm having the same problem. IA, please help.... At least provide some documentation on getting the "allocated string buffer (MAX_PATH length)" to work.

Dan Fisher
Posts: 15
Joined: Tue Sep 05, 2006 6:40 am
Location: UK

Postby Dan Fisher » Mon Dec 10, 2007 12:20 pm

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).
Dan

elecuyer
Posts: 13
Joined: Thu Jun 28, 2007 9:47 am
Location: Haverhill, MA
Contact:

Postby elecuyer » Mon Dec 10, 2007 12:31 pm

I did the same thing - write, then read from a temporary INI file. I'll give you 3 guesses as to the INI file's name :-)

DiVan
Posts: 4
Joined: Tue Jan 15, 2008 9:58 am

Postby DiVan » Mon Jan 28, 2008 9:54 am

I've succeded actualy...

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.

DiVan
Posts: 4
Joined: Tue Jan 15, 2008 9:58 am

restriction

Postby DiVan » Tue Jan 29, 2008 10:24 am

Only restriction on buffer (which is not cool) is MAX_PATH... for me it's 260 bytes.

mbond
Posts: 12
Joined: Thu Dec 12, 2013 9:37 am

Re: dll string parameter

Postby mbond » Wed Jan 08, 2014 8:49 am

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):

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

FrancescoT
Site Admin
Posts: 5360
Joined: Sun Aug 22, 2010 4:28 am

Re: dll string parameter

Postby FrancescoT » Wed Jan 08, 2014 12:15 pm

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


Return to “Technical Support”

Who is online

Users browsing this forum: Google [Bot] and 51 guests