I need to override the main program function and then call back the main program later. I know I can use -XM to set another function name besides "main" but then how do I call back the original function "main" later?
Regards,
Ryan Joseph

Mailing lists / fpc-pascal / 2020-01
9 messages · 4 people · –
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
I need to override the main program function and then call back the main program later. I know I can use -XM to set another function name besides "main" but then how do I call back the original function "main" later?
Regards,
Ryan Joseph
I know I can use -XM to set another function name besides "main" but then
how do I call back the original function "main" later?
I quickly analyze the generated assembly when you don't pass -XM:
.globl main
.type main,@function
main:
.globl PASCALMAIN
.type PASCALMAIN,@function
PASCALMAIN:
vs when you do (-XMmymain):
.globl mymain
.type mymain,@function
mymain:
.globl PASCALMAIN
.type PASCALMAIN,@function
PASCALMAIN:
so basically the original main does nothing and jump straight to PASCALMAIN, which is always there. So you can make your own main in a separate file that must be linked in during linking which calls whatever name you pass to -XM.
I need to override the main program function and then call back the main program later. I…
Ryan Joseph via fpc-pascal schrieb am
Do., 2. Jan. 2020, 18:11:
I need to override the main program function and then call back the main program later. I know I can use -XM to set another function name besides "main" but then how do I call back the original function "main" later?
What exactly are you trying to accomplish on which platform with which version?
Regards,
Sven
On Jan 2, 2020, at 2:51 PM, Sven Barth via fpc-pascal wrote: What exactly are you trying to accomplish on which platform with which version?
I'm making an iOS platform layer in the style of SDL which needs to use iOS's main loop which never returns until the program stops execution. Within the iOS callbacks I need to then callback into the programs main begin..end block so the user can establish their own event loop (which then uses threads to synch between the 2 event loops).
I've got the SDL source code but I'm not understanding how they get control back to the user even using the -XM flag. They have a function:
extern C_LINKAGE int SDL_main(int argc, char *argv[]);which they call from within the iOS event loop and that calls the programs main functions which was defined using -XMSDL_main
Sorry if that doesn't make sense but I barely understand the problem myself.
Regards,
Ryan Joseph
I still can't figure out how -XM works. Can anyone provide an example? When ever I try to use it I get linker errors.
I've basically just started with a trimmed down program that does nothing but define an external new main function (like SDL does). From the SDL sources I thought that it would now point to the main program body but I can't get past linker errors.
fpc main.pas -XMuser_main
Undefined symbols for architecture x86_64:
"_P$TEST_$$_USER_MAIN$LONGINT$PCHAR$$LONGINT", referenced from: _PASCALMAIN in main.o
"_main", referenced from:
start in crt1.10.5.o
(maybe you meant: _user_main)
program test;
uses
ctypes;
function user_main(argc: cint; argv: pchar): cint; external;
begin
user_main(0,'');
end.Regards,
Ryan Joseph
You're missing a "cdecl;" here.
begin user_main(0,''); end.
Additionally, you will also have to link in an object/library that does define a regular "main" function. And note that this will only work on libc-based targets (afaik only Darwin, Solaris, and AIX at this point).
Jonas
So there needs to be a function named "main" that is linked to directly or can it just be in a unit? I tried doing this but still get linker errors (tested on MacOS of course). My example program is below.
It's possible I think -XM does something it doesn't also so here's is the main function for the SDL/ios bindings. Note how UIApplicationMain is called which then never returns control until the program exists. After that within the iOS event handlers a call is made to SDL_main (see the external definition) which if I understand correctly is set using -XP and this then in turn calls the begin..end block of the main Pascal program. Is that correct?
extern C_LINKAGE int SDL_main(int argc, char *argv[]);int main(int argc, char **argv)
{
int i; /* store arguments */
forward_argc = argc;
forward_argv = (char **)malloc((argc+1) * sizeof(char *));
for (i = 0; i < argc; i++) {
forward_argv[i] = malloc( (strlen(argv[i])+1) * sizeof(char));
strcpy(forward_argv[i], argv[i]);
}
forward_argv[i] = NULL;
/* Give over control to run loop, SDLUIKitDelegate will handle most things from here */
@autoreleasepool {
UIApplicationMain(argc, argv, nil, [SDLUIKitDelegate getAppDelegateClassName]);
}
/* free the memory we used to hold copies of argc and argv */
for (i = 0; i < forward_argc; i++) {
free(forward_argv[i]);
}
free(forward_argv);
return exit_status;
}Later on in the event handler called from UIApplicationMain:
// call the user program main function so they can enter their own event loop logic
exit_status = SDL_main(forward_argc, forward_argv);=================================================
here is my test case:
fpc main.pas -XMuser_main
unit umain;
interface
uses
ctypes;
function user_main(argc: cint; argv: pchar): cint; cdecl; external;
function main(argc: cint; argv: pchar): cint;
implementation
function main(argc: cint; argv: pchar): cint;
begin
result := user_main(args, args);
end;
end.
program main;
uses
umain;
begin
writeln('called user main');
end.The linker error I can't get past:
Undefined symbols for architecture x86_64:
"_main", referenced from:
start in crt1.10.5.o
(maybe you meant: _user_main)
Regards,
Ryan Joseph
The OS startup code always calls a C function called "main" with the default C main function arguments. By default, FPC names the main entry point symbol of the program "main". -XM simply changes this name.
Your errors are that your main function in your unit
1) is not declared as "cdecl", so it uses the wrong calling convention
2) additionally, is not declared as "public", so the only the default (Pascal-mangled) symbol is created for it (in combination with cdecl, this will add a C-mangled alias to it).
So add 'cdecl; public;" to its declaration and definition.
Jonas
On Jan 3, 2020, at 12:29 PM, Jonas Maebe wrote: So add 'cdecl; public;" to its declaration and definition.
Nice the demo program compiles now.
Regards,
Ryan Joseph