How can I properly statically link C with Delphi? Delphi spits out an error saying:
[dcc32 Error] Project1.dpr(15): E2065 Unsatisfied forward or external declaration: 'Test'
The C compiler is Visual C++ with COFF object file.
Delphi:
program Project1;
{$L C:\Source.obj}
function Test(): Integer; cdecl; external;
begin
WriteLn(Test);
end.
C:
extern "C" int __cdecl Test()
{
return 12;
}
int main()
{
return 0;
}
It depends on the name decoration used by whichever C compiler you are using. For example, the 32 bit bcc32 compiler will decorate Test
as _Test
. So the Delphi code to link to it should be:
function Test(): Integer; cdecl; external name '_Test';
But the decoration does vary between compilers, and you did not say which compiler you are using. If the code above doesn't help, then you should use your C compiler's tools to dump the obj file and inspect the names of the functions within.
Another problem is that you are actually using a C++ compiler rather than a C compiler. That can be discerned from your use of
extern "C"
which is not valid C. You should remove this and switch to a C compiler. Changing the extension from .cpp to .c will usually suffice to persuade the compiler to treat the code as C.
If you start calling functions from the C standard library, such as malloc
and friends, then you will want to add the System.Win.Crtl
unit to your Delphi code's uses clause.
Note also that you need not, and indeed probably should not, implement a main
function in your C code. If you want to compiler your C functions into a separate C program then place the functions in separate source files, apart from the source file that contains the main function. That way you can compile the source files into objects. You can link them into either a C program, or your Delphi code. But you don't need to carry around a main
function in your Delphi program that you don't call.
In C the correct signature for a parameterless main
is
int main(void)
Similarly, your other C function should have this signature:
int __cdecl Test(void)
Of course, the __cdecl
is the default, so we are perfectly at liberty to omit it:
int Test(void)
Let's put it all together:
C
int Test(void)
{
return 12;
}
Important that you compile with a C compiler and do not compile as C++. If your compile is, as you now state in an edit, MSVC, the command line would be:
cl /c source.c
Delphi
{$APPTYPE CONSOLE}
{$L Source.obj}
function Test: Integer; cdecl; external name '_Test';
begin
WriteLn(Test);
end.
Output
12
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With