14116
Goto Top

Allgmeiner FunctionWrapper für 3rd Party Funktionan

Hallo,

wir bekommen hier von einer externen Firma, .c und .h Files zur Verwendung. Diese Dateien werden regelmäßig von dieser Firma gewartet.
Meine Aufgabe ist es momentan, einen Funktionswrapper zu schreiben, welcher diese 3rd Funktionen ansprechen kann.

Unten ein Beispiel wie das Ganze auszusehen hat.

Ich hoffe das Ganze ist selbsterklärend genug.


Frage wie kann ich die va_list vor der Übergabe an die 3rdParty Funktionen so abändern, dass der Funktionspointer NICHT mitübergeben wird?


LG
Günter


---
#include <stdio.h>
#include <stdarg.h>



// --- Start Example of 3rd Party Functions ----
// ---    unmodifyable -------------------------


void f1(void)
{
   printf("f1\n");  
}

void f2(int param1, int param2)
{
   printf("f2: %d, %d\n", param1, param2);  
}

void f3(char *text, int param1)
{
   printf("f2: %s, %d\n", text, param1);  
}


// --- End of 3rd Party Functions --------------




//
// 3rd Party Function Wrapper
//
void functionwrapper( void(*func)(), ...)
{
   va_list argptr;

   (*func)(argptr);
}



//
// Main
//
int main(void)
{
  functionwrapper(f1);  		// work
  functionwrapper(f2, 1, 2);  		// did not work
  functionwrapper(f3, "Text1", 2);	// did not work  

  return 0;
}

Content-Key: 260081

Url: https://administrator.de/contentid/260081

Printed on: April 23, 2024 at 10:04 o'clock

Member: rubberman
rubberman Jan 16, 2015 at 17:23:37 (UTC)
Goto Top
Hallo Günter,

so wie du dir das vorstellst, funktioniert das gar nicht.
  • Deine 3rd Party Funktionen akzeptieren keinen Parameter vom Typ va_list.
  • Woran sollte dein Programm denn erkennen, welche Funktion aufgerufen werden soll?

C++ (nicht C) würde die Möglichkeit bieten, deine Wrapperfunktion zu überladen. In dem Fall könntest du anhand Anzahl, Typ und Reihenfolge der Parameter unterschiedliche 3rd Party Funktionen aufrufen.

Mir leuchtet dein Konzept allerdings gar nicht ein. So wie du schreibst, werden Header-Dateien mitgeliefert. In denen sollten sich die Prototypendeklarationen der Funktionen finden. Wenn du also die Headerdateien inkludierst, kannst du auch direkt auf die Funktionen zugreifen. Wozu der Wrapper?

Grüße
rubberman
Member: rubberman
rubberman Jan 19, 2015 at 16:57:34 (UTC)
Goto Top
Ich hab noch mal etwas überlegt, wie das bei dir in der Realität aussehen könnte.
wir bekommen hier von einer externen Firma, .c und .h Files zur Verwendung. Diese Dateien werden regelmäßig von dieser Firma gewartet.
Könnte das bedeuten, dass die Dateien und Funktionen irgendwie namentlich versioniert sind?
Meine Aufgabe ist es momentan, einen Funktionswrapper zu schreiben, welcher diese 3rd Funktionen ansprechen kann.
Hmm. Am Ende ist das doch dann nichts anderes, als funktionA() in deinem eigenen Quellcode stehen zu haben, dafür aber funktionX() in den 3rd Party Dateien aufzurufen. Ggf. auch functionX_v1() für Version 1, falls diese irgendwie versioniert ist.

Falls das so oder ähnlich ist, dann würde ich das Ganze vom Präprozessor abfackeln lassen. Dieser führt vor dem Kompilieren eine Art von virtueller Textersetzung durch.
Vorteil: Dein Wrapper erzeugt keinen Programmcode, der mit kompiliert wird und letztlich die Performance beeinträchtigt.

Schau dir mal mein Beispiel an. Vielleicht kannst du eine Lösung für dich ableiten. Anderenfalls erkläre noch mal, wie das bei dir aussieht und bring mal ein möglichst realitätsnahes Beispiel von Soll und Ist ...

Grüße
rubberman

thirdparty_v1.c
#include <stdio.h>

void functionX_v1(const char *const szTxt)
{
  printf(szTxt);
}

int functionY_v1(void)
{
  return 42;
}


thirdparty_v1.h
#ifndef THIRDPARTY_H
#define THIRDPARTY_H

#ifdef __cplusplus
extern "C" {  
#endif {{comment_single_line_double_slash:0}}

// Prototypen der versionierten 3rd Party Funktionen.
void functionX_v1(const char *const szTxt);
int  functionY_v1(void);

#ifdef __cplusplus
}
#endif {{comment_single_line_double_slash:0}}

#endif {{comment_single_line_double_slash:3}}


wrapper.h
#ifndef WRAPPER_H
#define WRAPPER_H

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/** Die entsprechende Version als Appendix muss einmalig neu definiert werden. (anpassen) */
#define VERSION v1

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/** Macros für die Funktionalität des Headerwrappers. */
// 3.) In ein Stringliteral überführen.
#define HEADER_STR(hname) #hname
// 2.) Verkettung des Headernamens. (ggf. anpassen)
#define HEADER_CONCAT(ver) HEADER_STR(thirdparty_##ver.h)
// 1.) Auflösung des VERSION Macros.
#define HEADER(ver) HEADER_CONCAT(ver)

/** Einbindung des versionierten Headers */
#include HEADER(VERSION)

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/** Macros für die Funktionalität des Funktionswrappers. */
// 3.) Verkettung des Funktionsnames mit dem Unterstrich und der Version. (ggf. anpassen)
#define FUNC_CONCAT(func, ver) func##_##ver
// 2.) Auflösung des VERSION Macros.
#define FUNC_EVAL(func, ver) FUNC_CONCAT(func, ver)
// 1.) Übergabe des VERSION Macros.
#define FUNC(func) FUNC_EVAL(func, VERSION)

/** Macros für jede einzelne nicht-versionierte Funktion müssen definiert werden. (anpassen) */
#define functionA FUNC(functionX)
#define functionB FUNC(functionY)

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#endif {{comment_single_line_double_slash:6}}


main.c
#include <stdio.h>
#include "wrapper.h" 

int main(void)
{
  functionA("Die Antwort auf die Frage nach dem Leben,\ndem Universum und Allem ist ");  
  printf("%d.\n", functionB());  

  return 0;
}
Mitglied: 14116
14116 Jan 20, 2015 at 17:32:22 (UTC)
Goto Top
Hallo,

Danke für Deine Mühe.


Um mehr Verständnis reinzubringen:

Die C-Funktionen werden und zur Verwendung für Matlab geliefert. Der MEX-Compiler macht daraus "irgendeinen grauslichen" Code (hoffe das Du Matlab kennst).

Um das Ganze einfacher für meine "Ings..." und "Dipl. Ings." zu machen ist die Idee aufgekommen, einen Wrapper zu entwickeln.

Das das Ganze nicht Typensicher ist, sich hier nicht wichtig, bzw. allen bewusst.

Matlab würde hier ein .m Datei für lediglich EINE einzige Funktion erzeugen und nicht für 100erte...


Das wäre für uns ein Vorteil.


BTW: Ich sehe mir Deine Idee morgen/übermorgen im Labor an.


LG
Günter
Member: rubberman
Solution rubberman Jan 21, 2015, updated at Jan 28, 2015 at 12:03:28 (UTC)
Goto Top
Hallo Günter.

(hoffe das Du Matlab kennst)
Nee, leider nur vom Hörensagen.

Matlab würde hier ein .m Datei für lediglich EINE einzige Funktion erzeugen und nicht für 100erte...
Ups, bist du sicher?
Der Code für die jeweils aufgerufenen Funktionen befinden sich in deinen 3rd Party Dateien. Um darauf zugreifen zu können, musst du diese also einbinden und dem Compiler zugänglich machen. Da (zumindest bei C-Compilern) jede Quelldatei in separaten Übersetzungseinheiten kompiliert wird, die anschließend miteinander verlinkt werden, wird wohl auch deine 3rd Party Datei mit den hunderten Funktionen komplett kompiliert werden. Ich mache dir da wenig Hoffnung.

Ich weiß nicht was Matlab dir für Alternativmöglichkeiten bietet. Unter Windows (ich weiß nicht wie das auf anderen Betriebssystemen aussieht) gibt es da beispielsweise dynamisch gelinkte Bibliotheken (*.dll). Diese enthalten Funktionen die einmalig kompiliert wurden. Die unterschiedlichsten Programme können nun zur Laufzeit simultan auf diese vorkompilierten Funktionen zugreifen, ohne dass diese im eigenen Programmcode mit kompiliert werden mussten. Wenn etwas Ähnliches für Matlab existiert, wäre das wohl die einzig sinnvolle Alternative.

Grüße
rubberman