How to link C code containing WinAPI?

How can I link C code that contains calls in WinAPI? When binding, I get the following error:

[dcc32 error] Project1.dpr (16): E2065 Unsatisfactory forward or external declaration: '__imp__GetCurrentThreadId @ 0'

Consider the following example.

Delphi:

program Project1;

uses
  Windows;

{$L C:\Source.obj}

function Test: DWORD; cdecl; external name '_Test';

begin
  WriteLn(Test);
end.

FROM

#include <Windows.h>

DWORD Test(void)
{
   return GetCurrentThreadId();
}
+4
source share
1 answer

This is because Windows header files are usually used __declspec(dllimport)when declaring functions. For the function in question, its definition in WinBase.h:

WINBASEAPI
DWORD
WINAPI
GetCurrentThreadId(
    VOID
    );

When expanding all macros and reformatting that become:

__declspec(dllimport) DWORD __stdcall GetCurrentThreadId(void);

__declspec(dllimport) __stdcall , __imp__GetCurrentThreadId@0. , , SDK. Delphi, . . Delphi. , . Delphi .

Windows C , , . __declspec(dllimport). :

typedef unsigned long DWORD; // taken from the Windows header files

DWORD GetCurrentThreadId(void); // this is implemented in the Delphi code to which you link

DWORD MyGetCurrentThreadId(void)
{
   return GetCurrentThreadId();
}

Delphi

{$APPTYPE CONSOLE}

uses
  Winapi.Windows;

{$LINK MyGetCurrentThreadId.obj}

function _GetCurrentThreadId: DWORD; cdecl;
begin
  Result := Winapi.Windows.GetCurrentThreadId;
end;

function MyGetCurrentThreadId: DWORD; cdecl; external name '_MyGetCurrentThreadId';

begin
  Writeln(MyGetCurrentThreadId);
  Readln;
end.

. . __stdcall @XX , , , Delphi - @.

, , Windows.


. , , , __imp__GetCurrentThreadId@0 GetCurrentThreadId, . Delphi Winapi.Windows.


, Agner Fog objconv, . :

#include <Windows.h>

DWORD MyGetCurrentThreadId(void)
{
   return GetCurrentThreadId();
}

C

cl /c MyGetCurrentThreadId.c

.obj

objconv -nr:__imp__GetCurrentThreadId@0:GetCurrentThreadId MyGetCurrentThreadId.obj MyGetCurrentThreadId_undecorated.obj

Delphi

{$APPTYPE CONSOLE}

uses
  Winapi.Windows;

{$LINK MyGetCurrentThreadId_undecorated.obj}

const
   _GetCurrentThreadId: function: DWORD; stdcall = Winapi.Windows.GetCurrentThreadId;

function MyGetCurrentThreadId: DWORD; cdecl; external name '_MyGetCurrentThreadId';

begin
  Writeln(MyGetCurrentThreadId);
  Readln;
end.

, Winapi.Windows.GetCurrentThreadId. GetCurrentThreadId, _GetCurrentThreadId, const, . . , , @user15124, .

+2

Source: https://habr.com/ru/post/1612739/


All Articles