Recent

Author Topic: Incorporate dll in executable  (Read 4251 times)

Jones

  • Newbie
  • Posts: 4
Incorporate dll in executable
« on: March 30, 2022, 10:34:08 am »
Hi,

In my application, I use a dll (CoolProp.dll). I would like to incorporate this dll in the exe file, so that the user of my program only needs the exe file. How can I do this and how do I adapt my code?
For the moment, to call a certain function in the, still externtal, dll, really the only thing in the code is this:

function PropsSI(Output: PAnsichar; Name1: PAnsichar; Prop1: Double; Name2: PAnsichar; Prop2: Double; FluidName: PAnsichar): Double; stdcall; external 'CoolProp.dll';

Since I am not a developer, I am a fan of grandma explanations  ;)
Thanks!

MarkMLl

  • Hero Member
  • *****
  • Posts: 6686
Re: Incorporate dll in executable
« Reply #1 on: March 30, 2022, 10:45:04 am »
The FIRST thing you need to consider is whether the license of the DLL allows you to do that.

If the DLL were GPLed I'm pretty sure that what you're proposing would require that you release your entire application under GPL, while LGPL would be more tolerant.

If you aren't familiar with GPL etc., I suggest that Wikipedia would be a good starting point.

When somebody needs to do this sort of thing, it's far more common to find some sort of installation packager. However you'd still need to consider the legality of redistribution.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

HeavyUser

  • Sr. Member
  • ****
  • Posts: 397
Re: Incorporate dll in executable
« Reply #2 on: March 30, 2022, 03:50:05 pm »
Hi,

In my application, I use a dll (CoolProp.dll). I would like to incorporate this dll in the exe file, so that the user of my program only needs the exe file. How can I do this and how do I adapt my code?
For the moment, to call a certain function in the, still externtal, dll, really the only thing in the code is this:

function PropsSI(Output: PAnsichar; Name1: PAnsichar; Prop1: Double; Name2: PAnsichar; Prop2: Double; FluidName: PAnsichar): Double; stdcall; external 'CoolProp.dll';

Since I am not a developer, I am a fan of grandma explanations  ;)
Thanks!
For which operating system? and why not just copy two files? In windows for example placing both files in a zip archive windows will see it as a single zipped folder and it might work with a simple double click. On linux and other systems that is not an option.

440bx

  • Hero Member
  • *****
  • Posts: 4029
Re: Incorporate dll in executable
« Reply #3 on: March 30, 2022, 05:57:48 pm »
I would like to incorporate this dll in the exe file, so that the user of my program only needs the exe file. How can I do this and how do I adapt my code?
That's done by including the dll in the resource section of the program as a binary resource.  To load the dll, you have to write out the resource data (which is the dll) to a file (usually a temporary file) then load it (LoadLibrary)

HTH.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

af0815

  • Hero Member
  • *****
  • Posts: 1291
Re: Incorporate dll in executable
« Reply #4 on: March 30, 2022, 06:16:30 pm »
To load the dll, you have to write out the resource data (which is the dll) to a file (usually a temporary file) then load it (LoadLibrary)
And the AV is catching the program. To use a installer is safer. If the system is normal configured without the user is admin, you are not able to do this.
regards
Andreas

440bx

  • Hero Member
  • *****
  • Posts: 4029
Re: Incorporate dll in executable
« Reply #5 on: March 30, 2022, 08:03:54 pm »
And the AV is catching the program. To use a installer is safer. If the system is normal configured without the user is admin, you are not able to do this.
There are programs that do this with device drivers and the AV doesn't get in the way.  Though it might help that the device driver is signed by MS.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

HeavyUser

  • Sr. Member
  • ****
  • Posts: 397
Re: Incorporate dll in executable
« Reply #6 on: March 30, 2022, 10:01:13 pm »
In this case the application is statically linked to the dll. So errors of dll not found will come before any AV. It needs to be converted to dynamic loading linking and that is not easy for a non programmer.
« Last Edit: March 30, 2022, 10:08:01 pm by HeavyUser »

af0815

  • Hero Member
  • *****
  • Posts: 1291
Re: Incorporate dll in executable
« Reply #7 on: March 31, 2022, 07:32:26 am »
No it is not statically linked, it is only hidden in the resources of the dll. A dll like the described is normal created for dynamic linking. This is the reason you can load it at runtime and this load can be dynamic or static, not the dll itself. This are two different things.

If the the library is statically you include this code in your exe and make it monolithic. Normal this files are .lib in the win world. But a great problem is, you cannot convert a dynamic dll (with less work and tools) to a static one.

If you have the CoolProp.lib you can try to link it to the program direct. I have read this is possible, but never done.

CoolProp is open source, the codebase is here https://sourceforge.net/p/coolprop/git/ci/master/tree/ so it can be possible to create a lib and link in.

Quote
A cross-platform, open-source, alternative to NIST REFPROP. Based on reference-accuracy equations of state and transport property correlations for refrigerants like Water, CO2, R134a, Nitrogen, Argon, Ammonia, Air, R404a, R410a, Propane and many others. ...
MIT License
« Last Edit: March 31, 2022, 07:38:12 am by af0815 »
regards
Andreas

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2584
Re: Incorporate dll in executable
« Reply #8 on: March 31, 2022, 04:10:29 pm »
Technically it is possible on windows to load the embedded data in memory (which you have allocated as executable) call the windows loader/reallocator, to realloc the binary, and then load functions from it. This binary doesn't have to exist as file. I once read an article on how to do it, but I forgot where

Marc
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

balazsszekely

  • Guest
Re: Incorporate dll in executable
« Reply #9 on: March 31, 2022, 05:27:55 pm »
@Marc
Quote
Technically it is possible on windows to load the embedded data in memory (which you have allocated as executable) call the windows loader/reallocator, to realloc the binary, and then load functions from it. This binary doesn't have to exist as file. I once read an article on how to do it, but I forgot where
You can do it with BTMemoryModule.pas, I converted it to Lazarus. Just call method BTMemoryLoadLibary and BTMemoryGetProcAddress.

440bx

  • Hero Member
  • *****
  • Posts: 4029
Re: Incorporate dll in executable
« Reply #10 on: March 31, 2022, 05:39:15 pm »
@GetMem,

Nice little piece of code.  Unfortunately, it doesn't handle 64bit libraries but, it wouldn't take much to enhance it to handle those as well.

Thanks for sharing.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

HeavyUser

  • Sr. Member
  • ****
  • Posts: 397
Re: Incorporate dll in executable
« Reply #11 on: March 31, 2022, 05:56:46 pm »
No it is not statically linked, it is only hidden in the resources of the dll. A dll like the described is normal created for dynamic linking. This is the reason you can load it at runtime and this load can be dynamic or static, not the dll itself. This are two different things.
You miss understood, the original code is statically linked and I quote


For the moment, to call a certain function in the, still externtal, dll, really the only thing in the code is this:

Code: Pascal  [Select][+][-]
  1. function PropsSI(Output: PAnsichar; Name1: PAnsichar; Prop1: Double; Name2: PAnsichar; Prop2: Double; FluidName: PAnsichar): Double; stdcall; external 'CoolProp.dll';


With out a programmer/developer on the other end all this advice is only half instructions. It would be faster to post the application and some one does it for him.

balazsszekely

  • Guest
Re: Incorporate dll in executable
« Reply #12 on: March 31, 2022, 08:05:13 pm »
@440bx
Quote
Unfortunately, it doesn't handle 64bit libraries but, it wouldn't take much to enhance it to handle those as well.
Yes, the code is from 2005, IIRC Delphi only supports 64 bit starting with XE circa 2012. Looking at JwaWinNT.pas, I see that 64 bit headers are already declared, so you are right, it shouldn't be too difficult to handle 64 bit libraries.

Quote
Thanks for sharing.
You're more then welcome.

BobDog

  • Sr. Member
  • ****
  • Posts: 394
Re: Incorporate dll in executable
« Reply #13 on: March 31, 2022, 10:47:54 pm »
You can use ld.exe or in the bin folder x86_64-win64-ld.exe
I have a dll called vbcode.dll (use 64 bits, slight difference with 32 bits)
(as in a recent post of mine)

ld.exe -r -b binary -o vbcode1.o vbcode.dll  or

x86_64-win64-ld.exe -r -b binary -o vbcode1.o vbcode.dll

to get vbcode1.o

Then I use vbcode1.o to get the memory location of the dll.
I tried in pascal viz:
Code: Pascal  [Select][+][-]
  1.  
  2.  {$L vbcode1.o}
  3.  
  4.  function  memcpy(T:pointer;F:pointer;sz:integer):integer ; cdecl external 'msvcrt.dll' name 'memcpy';
  5.  
  6. var
  7. vbcode_dll_start :byte external '_binary_vbcode_dll_start' ;
  8. vbcode_dll_end :byte external '_binary_vbcode_dll_end';
  9. ublength:int32;
  10. s:ansistring;
  11.  
  12.  
  13.  procedure savefile(s:ansistring ;filename:ansistring);
  14.     var
  15.     fout:file;
  16.     begin
  17.     Assign(fout,filename);
  18.     Rewrite(fout,length(s));
  19.     blockwrite(fout,s[1],1);
  20.     close(fout);
  21.   end;
  22.  
  23. begin
  24. ublength:=@vbcode_dll_end - @vbcode_dll_start;
  25. writeln(ublength);
  26. setlength(s,ublength);
  27. memcpy(@s[1],@vbcode_dll_start,ublength);
  28.  
  29. savefile('libvbcodenew.a',s);
  30. end.
  31.  
  32. comments
  33.  
  34. my dll = vbvcode.dll
  35.  
  36.  ld.exe -r -b binary -o vbcode1.o vbcode.dll  or
  37.  
  38. x86_64-win64-ld.exe -r -b binary -o vbcode1.o vbcode.dll
  39.  
  40. to get vbcode1.o
  41.  
  42.  
But I get errors in Pascal with the object file. (Error: Failed reading coff file, invalid section index while reading vbcode1.o)
This method works perfectly well in freebasic.
If you look at the object file with nm

 nm vbcode1.o
0000000000047a00 D _binary_vbcode_dll_end
0000000000047a00 A _binary_vbcode_dll_size
0000000000000000 D _binary_vbcode_dll_start

If you get the object file loaded then fill the ansistring via memcpy (or the pascal equivalent).
Then save the string as a .a  or .o file.
If you then use this .a or .o file, it will substitute the dll, in fact it will be a part of the resultant .exe file which will be portable on it's own.
You need to define the exports after loading the .a or .o file, and I don't know how to define exported functions from an object file or a static lib file in freepascal.
I can find no easy way from help files so far.

The only difference with 32 bits is the first underscore before
_binary_vbcode_dll_end

_binary_vbcode_dll_start
There is no underscore used in 32 bits.
i.e.
binary_vbcode_dll_end

binary_vbcode_dll_start
Sorry I couldn't get a working runner, but I always fail miserably when I try to use .o or .a library files in freepascal.
Maybe you can tweak the above code to get that ansistring filled and saved in a file and use the file in your main program.







« Last Edit: April 01, 2022, 10:37:59 am by BobDog »

Jones

  • Newbie
  • Posts: 4
Re: Incorporate dll in executable
« Reply #14 on: April 01, 2022, 02:47:54 pm »
Hi all,
A warm thank you for the advice, nice to see that so much help is given in such a short time!
However, for now, I will leave the dll seperate from the executable, due to time constraints. Moreover, I guess calling the desired function form the dll will have to be coded differently when the dll is included in the exe via a resource file. Like HeavyUser mentioned, it requires developer skills to go beyond the scope of building applications in Lazarus.
Jones

 

TinyPortal © 2005-2018