Forum: PC-Programmierung #include "../main.c"


von Bauform B. (bauformb)


Lesenswert?

Guten Morgen!

Nochmal, weil es so schön ist:
1
#include "../main.c"
Gibt es dafür Schläge oder sogar eine spezielle Hölle? Weil, es ist 
überaus praktisch.

Es gibt ca. 60 Funktionen int foo(const char*); Die werden bisher alle 
in einem einzigen main() benutzt. Jetzt soll jede Funktion ein 
eigenständiges Programm werden und per klassischem CGI vom httpd 
aufgerufen werden. An den Funktionen selbst muss fast nichts geändert 
werden, die brauchen nur ein main() drum herum. Diese ca. 60 main() 
wären alle identisch, nur ist main.c z.Zt. noch ziemlich ausbaufähig:
1
#include <fcntl.h>
2
3
typedef int(*plugin_pt)(const char *);
4
extern plugin_pt plugin;
5
6
int
7
main (void)
8
{
9
   const char  *method, *uri, *query;
10
   int  fd;
11
12
   fd = open ("/var/log/bozo", O_WRONLY | O_APPEND);
13
   log_init (fd);
14
   method = getenv ("REQUEST_METHOD");
15
   uri    = getenv ("REQUEST_URI");
16
   query  = getenv ("QUERY_STRING");
17
   log_printf (1, "%s %s", method, uri);
18
   if (query == NULL) {
19
      query = "";
20
   }
21
   return plugin (query);
22
}
1
#include <stdio.h>
2
#include "foo.h"
3
//...
4
#include "../main.c"
5
plugin_pt plugin = foo;
6
7
int foo (const char *query)
8
{
9
}
: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ich würde es "main_impl.c" oder so nennen.
von Daniel A. (daniel-a)


Lesenswert?

Sowas würde ich per Linker lösen.
1
// include/server_framework/plugin.h
2
typedef void plugin_main_f(void);
3
extern plugin_main_f plugin_main;
1
// src/plugin/a/main.c
2
#include <stdio.h>
3
#include <server_framework/plugin.h>
4
void plugin_main(void){ printf("Plugin A\n"); }
1
// src/plugin/b/main.c
2
#include <stdio.h>
3
#include <server_framework/plugin.h>
4
void plugin_main(void){ printf("Plugin B\n"); }
1
// src/server_framework/main.c
2
#include <server_framework/plugin.h>
3
int main(){ plugin_main(); }
1
cc -I include/ src/server_framework/main.c -c -o server_framework_main.o
2
cc -I include/ src/plugin/a/main.c -c -o plugin_a.o
3
cc -I include/ src/plugin/b/main.c -c -o plugin_b.o
4
cc server_framework_main.o plugin_a.o -o plugin_a
5
cc server_framework_main.o plugin_b.o -o plugin_b

src/server_framework/* kann man natürlich auch in eine Library packen, 
statisch oder dynamisch geht beides. (Zumindest unter Linux, unter 
Windows geht vermutlich nur statisch, wenn da die main drin ist).
1
mkdir lib
2
cc -fPIC -I include/ src/server_framework/main.c -c -o server_framework_main.o # -fPIC brauchts nur für shared libs
3
ar r lib/libserver_framework.a server_framework_main.o # Statische lib
4
cc -shared lib/libserver_framework.a -o lib/libserver_framework.so # Optional, dynamische lib
5
6
cc -Llib plugin_a.o -o plugin_a -lserver_framework
7
cc -Llib plugin_b.o -o plugin_b -lserver_framework
8
9
// LD_LIBRARY_PATH falls dynamische Library verwendet wird. Alternativ, in /usr/local/lib installieren und ldconfig aufrufen
10
LD_LIBRARY_PATH=$PWD/lib/ ./plugin_a
(Unter Windows kann man nicht das selbe Archiv für die Statische lib und 
die DLL nehmen, dort braucht man für die .o / .obj schon andere 
Optionen)

Muss man halt einmal ein Makefile dafür erstellen.

PS: Ich nehme gerne -Wl,--whole-archive libserver_framework.a 
-Wl,--no-whole-archive damit keine undefinierten oder doppelten Symbole 
wegen Linkerreihenfolge rumschwirren
: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Wenn eine Problem anscheinend eine Lösung erfordert, die signifikant von 
den sonst üblichen Vorgehensweisen abweicht, ists meistens ein 
xy-Problem.

C hat Includefiles üblicherweise als Header, und die toolchain bietet 
einen linker. Das reicht.

C bietet aber auch immer die Möglichkeit, sich sehr effektiv und mit 
Erfolgsgarantie selber in den Fuß zu schiessen.

Oliver
von Cyblord -. (cyblord)


Lesenswert?

Bauform B. schrieb:
> Gibt es dafür Schläge oder sogar eine spezielle Hölle?

Dafür gibts nur die Entlassung.
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Muss es denn unbedingt #include sein? Warum nicht die main.c ganz normal 
kompilieren und dazu linken? Ggf. per "-D" Compiler Option den Namen der 
gewünschten Funktion als Makro definieren.
von Bauform B. (bauformb)


Lesenswert?

Ja, ok, überzeugt :)

Daniel A. schrieb:
> src/server_framework/* kann man natürlich auch in eine Library packen,
> statisch oder dynamisch geht beides.

Diese Funktionen benutzen sowieso eine shared library. Ich hab' jetzt 
mal nichts weiter gemacht als main da rein zu packen (die include-Datei 
ist jetzt leer). Das funktioniert ohne weitere Änderung sofort. Das 
Beste: die 60 Programme müssen nach Änderungen an main nicht neu gelinkt 
werden. Allerdings ist main() jetzt wirklich gut versteckt ;)

Die Namen der Funktionen möchte ich nicht ändern, manchmal ist _func_ 
ganz nützlich. Also behalte ich den Funktionspointer; ein Makro 
funktioniert ja nicht, wenn main() in der lib steckt.

Vielen Dank für Trost und Rat!

Oliver S. schrieb:
> C bietet aber auch immer die Möglichkeit, sich sehr effektiv und mit
> Erfolgsgarantie selber in den Fuß zu schiessen.

Deswegen frage ich ja Euch ;)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.