Is there a performance limitation when accessing the Windows API through Delphi?

I have programming experience with the old Win32 API in C ++ several years ago, and recently I participated in development with Delphi. I immediately learned many functions from the Windows API (e.g. CreateThread , CreateWindowEx , etc. Etc.).

I found the Embarcadero documentation is incomplete (at least) and usually refer to the Microsoft website for documentation. Wherever I could add, all functions are defined in C, which makes it difficult for non-C folks to work (but easier for me).

What I want to know is that the signatures of the Delphi functions are identical to the signatures of the C functions provided by Microsoft - does the call to the Windows API function Delphi immediately call the Windows API function, or does it call the identical Delphi function, which then calls the Windows API function and returns a result, the first means there is no distinguishable difference in performance compared to the corresponding C code, while the later means something like performance is fine?

+8
c ++ winapi delphi
source share
2 answers

Read the source. The CreateWindowEx call is defined in the Windows.pas module as a direct call to the CreateWindowExW in User32.DLL (from the XE5 source - similar definitions are found in all versions of Delphi for supported OS versions):

 function CreateWindowEx(dwExStyle: DWORD; lpClassName: LPCWSTR; lpWindowName: LPCWSTR; dwStyle: DWORD; X, Y, nWidth, nHeight: Integer; hWndParent: HWND; hMenu: HMENU; hInstance: HINST; lpParam: Pointer): HWND; stdcall; external user32 name 'CreateWindowExW'; 

So, the answer to your specific question is no. No execution penalty. Calling a WinAPI function in Delphi does not affect performance.

+20
source share

Does calling the Windows Delphi API function call the Windows API function right away?

This is not true.

For an argument, consider calling CloseHandle . This is declared in the Windows module and implemented using external . When you call it, you are actually calling a function called CloseHandle in the Windows module. Therefore, in pseudo-assembler, it looks like this:

 .... prepare parameters CALL Windows.CloseHandle 

Then Windows.CloseHandle is executed as follows:

 JMP kernel32.CloseHandle 

Thus, compared to a direct call, there is a call to the thunk function, and then a transition to the Win32 DLL. This is known as a trampoline.

It can be implemented in different ways. The compiler can emit code for direct invocation in the Win32 DLL. And some compilers will do it. For example, the equivalent asm for this call coming from MSVC would be:

 CALL DWORD PTR [__imp__CloseHandle@4] 

Here __imp__CloseHandle@4 is the memory location address that contains the CloseHandle address in the Windows DLL. The loader writes the actual CloseHandle address to __imp__CloseHandle@4 at boot time.

Which is more efficient? It is impossible to say for sure without profiling. But I am sure that any difference will be significant in a vanishingly small number of cases.

Of course, it is also possible to generate code that calls directly without indirectness. This will include a bootloader patch for each function call. This is probably a bad idea, as it will lead to a lot of load time fixes that will be a performance issue at startup. However, it will be almost the same as the DLL that must be ported at boot time. In any case, I do not know a single chain of tools that applies this policy.

You may be worried if these features are genuine Win32 features. Or there is a layer around them that makes sense. These are real Win32 features. There is no Delphi documentation as these are Win32 features. Win32 Documentation on MSDN is an authoritative source of documentation.

Like many people, Win32 functions are called without an intermediate layer. Therefore, in this sense, they are explicitly called that your parameters are passed unchanged in the API functions. But the calling mechanism is indirect in the sense that it uses a trampoline. Semantically, there is no difference.

+10
source share

All Articles