When you compile a DLL in Delphi XE6, it automatically exports the function TMethodImplementationIntercept from System.Rtti.pas. I tried to find a way to avoid this export but didn't find any configuration or compiler directive that could do the trick.
The System.Rtti unit is nearly impossible to avoid because it's used indirectly by almost everything in delphi.
Is there a way to avoid exporting this function when building a DLL in XE6?
The code in the System.Rtti unit looks like this:
{ This function has been added to be used from .s .c files in order to avoid use mangled names}
procedure TMethodImplementationIntercept(const obj:TMethodImplementation; AFrame: Pointer); cdecl;
begin
obj.Intercept(AFrame);
end;
exports TMethodImplementationIntercept;
This function and the exports directive, were added in XE5.
Is there a way to avoid exporting this function when building a DLL in XE6?
If your library includes the System.Rtti unit then the DLL will export that function. If you want to produce a DLL that does not export the function I can see the following options:
Use an older version of Delphi.
Don't include System.Rtti in your library.
Use a modified version of System.Rtti that does not export the function.
Modify the DLL after it has been produced to remove the function from the PE export table.
The first two options seem to me to be not very appealing. The third option seems attractive but I think it might turn out to be difficult to make work. It seems that this long standing trick no longer works. I've not yet been able to re-compile an RTL unit and avoid the dreaded X was compiled with a different version of Y error.
So that leaves the final option. Again, not massively attractive. You may well decide to just suck it up and accept this stray export. Perhaps a QC report might put a little pressure on Embarcadero to reconsider this decision.
For what it is worth, in my opinion no compiler library code should ever unconditionally export a function. It should be the consumer of the library rather than the implementer of the library that takes that decision.
Related
To determine my exe path, I don't know which code I should use.
Please give me explanation when and why should we use:
1. ExtractFilePath(ParamStr(0))
2. ExtractFilePath(Application.ExeName)
Because both code are rendering the same output.
C:\Users\Bianca\Documents\RAD Studio\Projects\Exam1\Win32\Release\
C:\Users\Bianca\Documents\RAD Studio\Projects\Exam1\Win32\Release\
They both give you the same result, but there are subtle differences.
Application.ExeName references the VCL Application object. The use of this property requires you use the Vcl.Forms unit. Internally this does call the ParamStr(0) function.
Notice that the FireMonkey TApplication class does not have this property (as of XE5). So you cannot call Application.ExeName if you are using FireMonkey. And if you ever migrate a VCL project to FireMonkey you will have to rewrite this.
The ParamStr function OTOH is the System unit and is multiplatform (Win, Mac, iOS and Android, depending OC on the Delphi version you are using). On Windows ParamStr(0) calls the GetModuleFileName function, while on the other platforms it parses the command line returning the first token, which should be full path and name of running executable. (Thanks to Rob Kennedy for this correction)
So... I'd suggest you use ParamStr(0) directly.
They are functionally identical. You would use ParamStr(0) if you didn't want the overhead of the Forms unit and all it's baggage.
I'm writing my own component in Delphi XE2 but I primary use C++ Builder. That is why I need some help regarding Delphi DCrypt library.
My new component needs to have a method (function) that calculates sha256 hash value of a string. I know for DCrypt library and I use it for some time but this time I need to isolate SHA256 hash algorithm and add it in my new component.
DCrypt has stored SHA256 in DCPsha256.pas but since I'm not so skilled in Delphi I don't know what to do. I don't need to install TDCP_sha256, I just need to be able to calculate SHA256 inside my new component.
Ideas? Thanks.
Create the objects manually. Use the existing units and do not modify DCPCrypt.
How to create an object:
var
x:TDCP_sha256;
begin
x := TDCP_sha256.Create(nil);
try
// do stuff, create hash, whatever.
finally
x.Free;
end;
end;
You do not need to install any packages in order to provide access to the classes that you want to use, unless you wanted to drop them onto a form or data module. If you write code like the above code, you don't need to modify anything.
one: do not do. It better to distribute DCrypt library with ur component and allow user to update it to more recent versions.
If sha256 would turn buggy, or incompatible with newer Delphi version - what would you do ? If u use DCrypt, then you just download new version of it. If you isolated it - then u have to fix it yourself. Do you have enough skils in both Delphi and crypto mathematics, to always doo all fixes of sha256 code and new Delphi versions in future ?
But if you insist - then launch to Delphi side by side. In one open DCrypt sources, in another open new empty unit. Copy sha256-generating procedure from DCrypt to empty unit and try to compile. Delphi would tell you of unknown identificators. Look into Dcrypt Delphi and find the declarations of them. If they are from DCpypt too - then copy them again into the new unit. If they are from RTL/VCL - add the unit into USES of your new unit. And try to compile again. Repeat this until all the identifiers are either resolved by USES or copied from DCrypt into your file.
After it compiles - take some file and calculate hashes by DCrypt and by you new library - if they are different, that means you had borken something and have to find and fix it (you have enought crypto math experience, don't you).
I made Win64 asm optimizations for Spring4D sha code and all that code was covered by unit tests, so i always new if my optimizations broke things or not. Without those total testign policy i'd not be able to do it.
I strongly advice you to stick with DCrypt or Lockbox3 or Spring4D or any other strong living library and not isolate yourself. Keep together with community and you can use their labor for yourself. Isolate - and you would have to re-do it each time new bug or incompatibility would face up.
You cannot extract code from library - why do you think you would be able to upgrade that code to XE4/5/6... and prove it was not broken ?
Is there a real difference between C++ dlls and Delphi dlls?
A application loads only C++ dlls.
Changing calling convention to cdecl is of no use
Is there a way to find whether a dll is a C++ dll?
What is the advantage of that dll?
I mean a Delphi dll can have parameters and/or return type of Delphi.
Like that C++ dll may have some exclusive data type/
Thanks for any hint
C++ dlls can, of course, use or expose C++-specific items (C++ classes, template functions, etc.), and a Delphi DLL could expose Delphi-specific items (sets, strings, etc.). But if both are written properly, and only use things other languages can use too, there should be no difference.
Fact is that not all C++ or Delphi DLLs are written properly. Also the default calling convention in Delphi is register (__fastcall in C++Builder), while C and C++ by default use cdecl. But generally both languages should use stdcall.
The only way to use a DLL is to either get a header file (.h) for it, or a Delphi import unit. The .h file can be translated into an import unit. If you only have a DLL but none of these, it doesn't make much sense to try to guess the parameters of functions.
If you look at the DLL with TDUMP.exe or Dependency Walker, you might get a hint, as was said in another answer. Dependency on e.g. msvcrtXX.dll might be a good hint it is a C++ DLL.
You might also try to get a .tlb from the DLL. You can do this in the IDE (From memory: "Component menu" - "import component" or some such).
If you want to know the calling convention, read this, especially the part about finding out the calling convention.
Addition
Some C++ programmers forget to wrap their declarations in extern "C" blocks, so the exported functions are mangled. This could tell you which parameters are required, but you get ugly names. For this, Dependency Walker is a great help, as it can translate them (for VC++ generated or compatible DLLs at least). It makes using those functions from a different C++ compiler or a C compiler pretty hard, though.
You can use Dependency Walker to examine the functions in DLLs:
http://dependencywalker.com/
I have a class in a unit. Usually, when I changed the algorithm of its methods, I have to recompile it and deliver the patch as a whole.
I think to create the instance of the class using DLL. After searching in delphi.about.com, I found that instead of using DLL, I can use BPL. It is a DLL for Delphi. The problem is almost all examples I found is only telling how to export a function.
I want to dynamically load the BPL, and whenever I replace the BPL, I can get the latest algorithm of the class, not only the functions I export.
Article I have read:
- http://delphi.about.com/od/objectpascalide/a/bpl_vs_dll.htm
- Plugins system for Delphi application - bpl vs dll?
- http://delphi.about.com/library/weekly/aa012301a.htm
Any URL or SAMPLE how to create a BPL from scratch to encapsulate a component or a class is greatly appreciated.
Dear Guru,
Suppose I have code like this:
unit unitA;
interface
type
B = class(TObject)
public
procedure HelloB;
end;
A = class(TObject)
public
function GetB: B;
function HelloA: String;
procedure Help;
end;
implementation
uses
Dialogs;
{ B }
procedure B.HelloB;
begin
ShowMessage('B');
end;
{ A }
function A.GetB: B;
begin
Result := B.Create;
end;
function A.HelloA: String;
begin
Result := 'Hello, this is A';
end;
procedure A.Help;
begin
//do something
end;
end.
I want to export all public methods of A. How to make it a DLL?
How to use it from another unit where to import it?
let's say:
var a: A;
a := A.Create;
a.GetB;
showMessage(a.HelloA);
A is not declared in the unit (it is in the DLL).
Please advise.
Hurray. I got it last night. All I have to do is make the object implement an interface which is used in the caller unit to catch the instance of object returned by the DLL.
Thank you all.
Mason nailed it already, but let me elaborate on why BPLs aren't what you are looking for.
BPLs are a means for the Delphi IDE to load components that share the same memory manager and RTL. (Type identity works almost transparently using BPLs)
However, the dependencies you are getting tied up in are almost always unacceptable. Except for the IDE, which cannot handle different versions of RTL and VCL anyway.
When you pass only interface references between your application and its DLLs, then you don't have to share RTL, VCL or shared packages at all.
It also means that you could write some DLLs in another language (C++, C#, FPC, another Delphi version), and still use objects. Which can be tempting when you don't want to port your main app but still want to use existing libraries that are not available for Delphi, or your version of Delphi.
The problem with putting a class in an external file is that your main application needs to know some way to refer to it. It will either have to descend from a base class that exposes all the methods you need as virtual methods, or implement an interface that contains all the functionality you need from it.
If you already know what the interface of the object should look like, and all you're changing is implementation details such as internal algorithms, probably the easiest thing would be to make your class implement an interface and put it in a DLL that exports a function that returns an instance of this interface. That way you don't need to worry about breaking your app up into packages, which can be a real hassle.
I see nothing in your problem description suggesting you would need to explicitly export anything from the package or that you would need to load it dynamically at run time. Instead, it's enough that your functions reside in a run-time package that can be replaced separately from the main program.
Start a new package project and move your class's unit into that project along with any other units it depends on. Compile the project. If the compiler warns about "implicitly including" any other units, add those to the package, too.
Now, remove any of the package units from the EXE project. There should be no units that are members of both projects. Next, turn on the "build with run-time packages" checkbox in your EXE's project options. Add your package to the semicolon-separated list of package names. The RTL and VCL packages will probably also be on that list.
Compile both projects, and you're done.
If you make changes to your class implementation, you can recompile the package only and send a new version to customers. The program will automatically get the new changes when you replace the original file with the new one. The package is listed in the program's import table, so the OS will automatically load the BPL file when it loads the EXE. The EXE doesn't need to run any special code to load the package.
Delphi can create DLL to export functions or BPL to export component.
You can create component, compile it (use the same compiler settings as in your main app), and Delphi will create .bpl. Then import this component to Delphi and compile your app with this compomponent as a package.
My experience with components created with Delphi 4 proved that one, big application is more reliable than application with separate .bpls. It was multithreaded server and it worked fine if compiled standalone, while crashed after short time if compiled with packages. I hope newer versions of Delphi improved in this area.
Be aware of memory management (in app do not free memeory allocated in package and vice versa) and compiler settings.
If you like about.com then this link will be useful: Introduction to Packages; BPLs are special DLLs!
BPLs have their usage. For example if you have to make a very huge application like an Erp, you need to try to use BPLs seriously.
In the other hand, BPLs aren't responsible of crashing applications. Bad usage of BPLs does it.
you can try the MAF Components, they handle plugins and much more for you without extra code. Comes with tutorials and a demo application with source.
http://www.maf-components.com
Has anyone come across a framework or library for Delphi to simplify the generation of x86 code? I am not looking for an assembler, but rather a framework that abstracts the code generation process above the low level bits and bytes. Ideally I would like to build on top of an existing library or framework rather than hardcode the logic on a case by case basis.
The initial usage will be to generate small code stubs at runtime similar to the way Delphi dispatches SOAP requests. If I cannot find something I will likely roll my own, but I would hate to reinvent the wheel. Something in "C" might me interesting provided the license will permit translation and use in commercial and open source projects.
Update:
Here is some more context: What I am working toward is runtime implementation of interfaces and/or classes as part of a persistence framework. Something sort of like Java annotation driven persistence (JPA/EJB3) except with a distinctly Delphi flavor. The invocation target is a modular/extensible framework which will implement a generalized persistence model. I need to dispatch and hook method calls based on RTTI and an annotation/attribute model (something similar to InstantObjects metadata) in a very dynamic and fluid manner.
Thanks,
David
The more I have thought about your question. I am not sure if all you trying to just do Dynamic Method Invocation. Even though your asking about generating x86 code.
There are several techiniques that do this.
If you know the signature of the method in question you can do it easily by using a
TMethod and setting the method address and data.
procedure TForm8.Button1Click(Sender: TObject);
begin
Showmessage('Hello1');
end;
procedure TForm8.Button2Click(Sender: TObject);
var
M : TMethod;
begin
M.Code := MethodAddress('Button1Click');
M.Data := Self;
TNotifyEvent(M)(self);
end;
If you don't know the method signature you can write the class with {$METHODINFO ON}
Then use the functionality in ObjAuto.pas to invoke the method.
I have an example in my RTTI Presentation code from DelphiLive on how to do that.
According to features of PaxCompiler, you can create stand alone executable files.
Very spectulative answer:
Something like LLVM? I am not sure if it can be used from delphi or not, but you should be able to create dll's wth it.
Logically you would simply generate delphi code, compile to a DLL/BPL by cmdline compiler and then dyn load that one?
Unfortunately Delphi Explorer doesn't come with the cmdline compiler though. And your main binary would also have to be in Delphi Explorer (or at least in D2006 if that is binary compatible enough)
Any mix of Delphi versions (or Free Pascal) will probably not work on the package or HLL level, only at basic procedural DLL level.
I just found an interesting framework that does much of what I was looking for when I originally posted the question. A little late for my purposes, but thought someone else might find this useful:
DAsmJit a Delphi port of the asmjit project