Wie zu zwingen, die Aufnahme der "unbenutzt" - Objekt-Definitionen in einer Bibliothek

Meine Frage ist ähnlich wie diese, aber scheint nicht zu korrelieren genau:

Wie force die Aufnahme einer Objekt-Datei in eine statische Bibliothek als Verlinkung in ausführbare?

Zwingen symbol exportieren mit MSVC

Was ich habe, ist so etwas wie so:

struct thingy;
struct container
{
  static container& instance(); //singleton

  int register_thingy(thingy*);
};

struct thingy
{
  virtual ~thingy() {}
  virtual int id() const = 0;
};

//template trick to force registration.
template < typename Derived >
struct registered_thingy : thingy
{
  registered_thingy() : my_id(my_static_id) {} 

  int id() const { return my_id; }
private:
  int my_id;
  static int my_static_id;
}
template < typename Derived >
int registered_thingy<Derived>::my_static_id = 
  container::instance().register_thingy(new Derived);

Nun, in einem concrete_thingy.cpp - Datei habe ich:

struct my_concrete_thingy : registered_thingy<my_concrete_thingy>
{
  my_concrete_thingy() {} //registered_thingy's constructor not called otherwise
};

Natürlich ist völlig nutzlos, aber es gibt Reale Verhalten abstrahiert hier.

Dies funktioniert wunderbar, wenn verwendet, in einer Anwendung, die zusammengestellt als ganzes. Das Problem ist jetzt, dass ich bin nicht in der Lage, so weit, um diese Technik zu nutzen, während Abfüllen bis das Verhalten hinter collection in einer Bibliothek. In anderen Worten, ich habe eine thingys.lib - Datei, die enthält concrete_thingy.cpp aber die Registrierung wird nicht ausgeführt, wenn das verbunden ist, um eine ausführbare Datei. Die collection endet bestehenden und arbeiten gut, aber es ist leer.

Nun, dies ist eine STATISCHE Bibliothek, keine DLL. Das ändert sich möglicherweise die Ausgabe ein wenig und die Techniken gesprochen, die in den oben genannten links scheinen nicht zu gelten. Die eine ist natürlich über die Funktionen und ich sehe nicht, wie ich es anwenden konnte, um diesen C++ - Strukturen.

Habe ich versucht, den #pragma comment Methode mit den folgenden drei Zeilen (einzeln natürlich) in concrete_thingy.cpp, keiner von denen gearbeitet:

#pragma comment (linker, "/export:concrete_thingy")
#pragma comment (linker, "/export:concrete_thingy::my_static_id")
#pragma comment (linker, "/export:registered_thingy<concrete_thingy>::my_static_id")

Wenn concrete_thingy.cpp ist in der ausführbaren Datei, anstatt die Bibliothek funktioniert alles einwandfrei.

Also dann, hier meine Fragen:

1) Ist es möglich, das zu tun, was ich versuche zu tun? Ich vermute ja, aber ich weiß nur nicht, wie.

2) Wenn es möglich ist, wie kann ich MSVC++ 2010 zu tun?

3) Wenn es möglich ist, wie könnte ich es in einen tragbaren Weg?

Kurz, was ich versuche zu tun, wäre ähnlich wie das erstellen einer abstrakten Fabrik, die schafft Implementierungen einer Abstraktion. Er weiß nichts über diese Implementierungen, die registriert sind, unter Verwendung der globalen Initialisierungs-Tricks. Dies sollten sich alle in eine statische Bibliothek, die verknüpft werden können, um durch eine Anwendung und diese Implementierungen verfügbar sein sollten, durch die Fabrik. Niemand weiß etwas über diese Implementierungen, mit Ausnahme von sich selbst und damit die normale Verknüpfung, ist das verursachen von Ihnen, und Ihre Registrierung globals, zu verschwinden.

Ist es nicht genau das, was ich bin, aber es ist nah genug.

Bearbeiten: ====================================================

Sieht wie das Verhalten ist "by design". MS erkennt, dass der Bau des Objekts, das Nebenwirkungen auftreten sollten, ob oder nicht, Ihr verwendet, Sie verwenden, um eine Lücke im standard, der es Ihnen ermöglicht nicht enthalten übersetzungseinheiten in dem nichts so ist, verwendet :\

https://connect.microsoft.com/feedback/viewfeedback.aspx?FeedbackID=244410&wa=wsignin1.0&siteid=210

/OPT:NOREF option soll nicht alles tun, in diesem Fall offensichtlich.

  • "registered_thingy Konstruktor nicht aufgerufen wird, ansonsten" -> es ist ein weiterer Weg, um das Problem zu lösen. Sie brauchen eine template<typename T, T&> struct refit; und dann kann man sagen, stattdessen definieren Sie einen Konstruktor, typedef refit<int, my_static_id> user; nach der static int Erklärung. Dies zwingt die Instanziierung des statischen zu. Siehe diese Antwort für die weitere Bearbeitung.
  • Scheinbar mal wieder gezeigt, dass der Unterschied zwischen einem bug und einem feature es ist, dass die Funktion dokumentiert ist. By the way ... ist wirklich die Vorlage, die Tricks nötig ? wäre nicht Folgendes besser funktionieren ? struct concrete : abstract { concrete(...) {} } concrete_instance(...);
Schreibe einen Kommentar