Hoe statische functie (in C) te laden vanuit een dynamische bibliotheek op Linux

Ik heb een statische functie "foo" in een foolib van een dynamische bibliotheek. Ik kan foolib met succes in mijn toepassing laden. Hoewel dlsym NULL retourneert voor "foo"

Zelfs nm-hulpprogramma geeft statische functie niet weer als een exporteerbaar symbool.

Ik begrijp dat de statische functie een bereik heeft dat beperkt is tot dat bestand.

Toch is er een manier om dit te bereiken.

Ik weet dat dit mogelijk is in C ++, weet niet hoe en waarom (kan gedeelde bibliotheek worden behandeld als object en functies in die bibliotheek als interfaces.)

1

1 antwoord

static is not just a "scoping" thing - static functions have internal linkage, so no information about their existence is written by the compiler in the object file; such information cannot be recovered later (while creating the dynamic library).

Nog beter: als het een kleine functie is, zal deze waarschijnlijk in elke omstandigheid worden onderstreept, en omdat het een interne koppeling heeft, is het niet nodig om de "stand-alone" versie te genereren, dus de functie zal niet meer bestaan ​​na de compilatiefase .

De enige praktische manier om een ​​adres voor zo'n functie "van buitenaf" te krijgen, is om een ​​andere functie in dezelfde vertaaleenheid te hebben (dwz in hetzelfde .cpp-bestand) die een pointer naar de foo functie, en exporteer vervolgens een dergelijke helperfunctie. Doenbaar, maar vrij zinloos als je het mij vraagt. :)


// In foolib

// The static function
static void foo()
{
   //...
}

// Typedef for the function pointer
typedef void (* fooFuncPtr)();

// Helper function to be exported - returns the address of foo
fooFuncPtr fooHelper()
{
    return &foo;
}

typedef void (* fooFuncPtr)();
typedef fooFuncPtr (* fooHelperFuncPtr)();

// In the client code of foolib
// ...
fooHelperFuncPtr fooHelper = (fooHelperFuncPtr) dlsym(handle, "fooHelper");
// ... in real code here you would have error checking ...
fooFuncPtr foo = fooHelper();
// now you can use foo
foo();
4
toegevoegd
@Nile: bewerkt antwoord. Maar nogmaals, het is compleet zinloos, omdat je, terwijl je er toch bent, statisch uit die functie kunt verwijderen in plaats van al deze rotzooi te creëren.
toegevoegd de auteur Matteo Italia, de bron
@Sodved: C ++ geeft nog een andere betekenis aan statisch wanneer het over lidfuncties gaat, maar het behoudt dezelfde betekenis als in C voor vrije functies, hoewel het was gemarkeerd als verouderd in de C ++ 98-standaard in voorkeur van anonieme namespaces (waarvan ik denk dat ze werden geïntroduceerd om lidfuncties van static toe te staan ​​interne koppeling te hebben). IIRC de slinger is opnieuw gezwaaid en nu in C ++ 11 is deze niet langer verouderd (zie [basic.link] in de standaard).
toegevoegd de auteur Matteo Italia, de bron
in C ++ wordt de betekenis van statisch gewijzigd als de functie een methode van een klasse is. Het betekent dat het een klassemethode is in tegenstelling tot een objectmethode. Als ik statisch gebruik op een normale functie (buiten een klasse), weet ik niet of een C ++ -compiler dit koppelt zoals de oude C-weg
toegevoegd de auteur Sodved, de bron
dus hoe is dit bereikt in C ++?
toegevoegd de auteur Nile, de bron