Hi folks,
I'm currently trying to call a Pascal routine from within a C program. To this mail I attached a few sources demonstrating the way I'm trying to do so. Compiling them with
gpc -c foo.pas gcc footest.c -o footest
leads to an error message "undefined reference to `Bar'".
What am I doing wrong?
Thanks in advance
Markus
On 7 Nov 2002 at 17:08, Markus Gerwinski wrote:
Compiling them with
gpc -c foo.pas gcc footest.c -o footest
leads to an error message "undefined reference to `Bar'".
The second command line doesn't include "foo.o", so the linker has no way to resolve "Bar". Try:
gcc footest.c foo.o -o footest
-- Dave
J. David Bryan wrote:
The second command line doesn't include "foo.o", so the linker has no way to resolve "Bar". Try:
gcc footest.c foo.o -o footest
Thanks. There's still something wrong, but at least the error message has changed. Now I get:
foo.o: In function `Bar': foo.o(.text+0x1c): undefined reference to `_p_stdout' foo.o(.text+0x21): undefined reference to `_p_write' foo.o(.text+0x2a): undefined reference to `_p_InOutRes' foo.o(.text+0x32): undefined reference to `_p_check_inoutres' foo.o: In function `init_Foo': foo.o(.text+0x5b): undefined reference to `_p_atexit' collect2: ld returned 1 exit status
What's wrong here?
On 7 Nov 2002 at 19:38, Markus Gerwinski wrote:
J. David Bryan wrote:
The second command line doesn't include "foo.o", so the linker has no way to resolve "Bar". Try:
gcc footest.c foo.o -o footest
Thanks. There's still something wrong...
My apologies. "gcc" doesn't know about the Pascal run-time library, which is needed to resolve the externals you listed. You can either tell "gcc" about the Pascal library:
gcc footest.c foo.o -o footest -lgpc
...although that depends on "gcc" being able to find "libgpc.a" in its default search paths, or you can have "gpc" run the linker ("gpc" already knows about the Pascal library):
gcc -c footest.c gpc foo.pas footest.o -o footest
-- Dave
Markus Gerwinski wrote:
I'm currently trying to call a Pascal routine from within a C program. To this mail I attached a few sources demonstrating the way I'm trying to do so. Compiling them with
gpc -c foo.pas gcc footest.c -o footest
leads to an error message "undefined reference to `Bar'".
What am I doing wrong?
a) You must link the Pascal object file:
gcc footest.c foo.o -o footest
b) You must init the RTS etc. (if the Pascal code uses any of it which most Pascal code does), see the demo programs gpc_c_pas.pas and gpc_c_unit.pas.
c) You should specify the asmname of the Pascal routine:
procedure bar; asmname 'Bar';
(Currently, this is the default used by GPC, but this will change soon as a preparationn for qualified identifiers, and you probably don't want your code to break then.)
Frank
Frank Heckenbach wrote:
a) You must link the Pascal object file:
gcc footest.c foo.o -o footest
I did so, getting another error message. (See parallel mail)
b) You must init the RTS etc. (if the Pascal code uses any of it which most Pascal code does), see the demo programs gpc_c_pas.pas and gpc_c_unit.pas.
Does this example mean, I have to write a pascal _program_ file just to ignore its "main"?! Isn't there a more explicit way to init the RTS?
c) You should specify the asmname of the Pascal routine:
procedure bar; asmname 'Bar';
(Currently, this is the default used by GPC, but this will change soon as a preparationn for qualified identifiers, and you probably don't want your code to break then.)
Certainly not... Did you already plot the new default rule GPC will use after the change? -- In fact, this means I'll _have_ to give every variable, routine etc. an asmname in order to keep my code gcc-compatible, right?
On Fri, Nov 08, 2002 at 11:23:54AM +0100, Markus Gerwinski wrote:
Does this example mean, I have to write a pascal _program_ file just to ignore its "main"?! Isn't there a more explicit way to init the RTS?
As long as you do not need any output with 'WriteLn' and such, you can write things like that:
=== foo.pas === unit Foo;
interface
function FooFunc (a: Integer): Integer; asmname '_c_foo_proc';
implementation
function FooFunc (a: Integer): Integer; begin FooFunc := a * a * 2 end;
end.
=== bar.c === #include <stdio.h>
extern int _c_foo_proc (int);
int main (void) { printf ("Now im Calling Foo with 3: %d\n", _c_foo_proc (3)); return 0; }
=== compile === gpc -c foo.pas gcc bar.c foo.o -lgpc -lm
Eike
Markus Gerwinski wrote:
Frank Heckenbach wrote:
a) You must link the Pascal object file:
gcc footest.c foo.o -o footest
I did so, getting another error message. (See parallel mail)
As other have pointed out, you also have to link the RTS (either explicitly `-lgpc -lm' or by using gpc for linking).
b) You must init the RTS etc. (if the Pascal code uses any of it which most Pascal code does), see the demo programs gpc_c_pas.pas and gpc_c_unit.pas.
Does this example mean, I have to write a pascal _program_ file just to ignore its "main"?!
No, this is just an example. You can also have just units/modules (and generally, this seems preferable). As the main program says:
WriteLn ('This is never called.');
So it does not intialize the RTS.
Isn't there a more explicit way to init the RTS?
The example C code does un-/initialize the RTS explicitly (_p_initialize/_p_finalize), as well as the Pascal unit and program init_pascal_main_program ().
If you have just units, you have to call init_Foo () (where Foo is the name of the unit) for each unit, except those which are used by other units (since their intializer is called by the other unit one's), but it doesn't hurt to call an initializer multiple times.
So I recommend to either call the initializer of all units, or to have a "top level" unit which uses all other ones, and call its intializer from C.
c) You should specify the asmname of the Pascal routine: procedure bar; asmname 'Bar';
(Currently, this is the default used by GPC, but this will change soon as a preparationn for qualified identifiers, and you probably don't want your code to break then.)
Certainly not... Did you already plot the new default rule GPC will use after the change? --
No, and I don't think we'll publish an "official" default naming so that ...
In fact, this means I'll _have_ to give every variable, routine etc. an asmname in order to keep my code gcc-compatible, right?
Yes. (Each one you use from C, of course.)
Frank
Frank Heckenbach wrote:
As other have pointed out, you also have to link the RTS (either explicitly `-lgpc -lm' or by using gpc for linking). ... The example C code does un-/initialize the RTS explicitly (_p_initialize/_p_finalize), as well as the Pascal unit and program init_pascal_main_program ().
If you have just units, you have to call init_Foo () (where Foo is the name of the unit) for each unit, except those which are used by other units (since their intializer is called by the other unit one's), but it doesn't hurt to call an initializer multiple times.
I did so now (see the sources attached), but it didn't really help. Compiling it with
gpc --automake -c foo.pas gcc -lgpc -lm footest.c foo.o -o footest
now yields the error message:
/tmp/ccPmuIkN.o: In function `main': /tmp/ccPmuIkN.o(.text+0x1b): undefined reference to `_p_initialize' /tmp/ccPmuIkN.o(.text+0x28): undefined reference to `_p_finalize' foo.o: In function `Bar': foo.o(.text+0x1c): undefined reference to `_p_stdout' foo.o(.text+0x21): undefined reference to `_p_write' foo.o(.text+0x2a): undefined reference to `_p_InOutRes' foo.o(.text+0x32): undefined reference to `_p_check_inoutres' foo.o: In function `init_Foo': foo.o(.text+0x5b): undefined reference to `_p_atexit' collect2: ld returned 1 exit status
What should I change?
Markus Gerwinski wrote:
I did so now (see the sources attached), but it didn't really help. Compiling it with
gpc --automake -c foo.pas gcc -lgpc -lm footest.c foo.o -o footest
now yields the error message:
What should I change?
Put the libraries after the other sources.
Frank
On Thu, 7 Nov 2002, Markus Gerwinski wrote:
Hi folks,
I'm currently trying to call a Pascal routine from within a C program. To this mail I attached a few sources demonstrating the way I'm trying to do so. Compiling them with
gpc -c foo.pas gcc footest.c -o footest
leads to an error message "undefined reference to `Bar'".
Since gpc is a patched version of gcc, gpc knows ".c" and this works:
gpc -c foo.pas gpc -o footest foo.o footest.c
Russ