<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[DLL Import von globalen Variablen]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe ein Problem, eine globale Variable aus einem Namespace einer DLL in einem Modul (weitere DLL) zu importieren. Folgendes Szenario:</p>
<p>Ich will eine Logging-Library verwenden (rlog), die als DLL kompiliert einige Klassen und eben auch Variablen bereitstellt, die sich in einem Namespace befinden:</p>
<p>Header-File rlog.h:</p>
<pre><code>/*! @file rlog.h
  @brief Defines macros for debug, warning, and error messages.

*/

// may be useful for checking from configuration files
#define CURRENT_RLOG_VERSION 20040503
extern &quot;C&quot; int RLogVersion();

namespace rlog
{

    class RLogChannel;
    class RLogPublisher;
    class RLogNode;

    /*! @enum LogLevel
      Logging level definitions.
    */
    enum LogLevel
    {
	Log_Undef    =0, //!&lt; undefined level
	Log_Critical,    //!&lt; critical conditions
	Log_Error,       //!&lt; error conditions
	Log_Warning,     //!&lt; warning conditions
	Log_Notice,      //!&lt; normal, but significant, condition
	Log_Info,        //!&lt; informational
	Log_Debug        //!&lt; debug level messages
    };

    void RLOG_DECL RLogInit(int &amp;argc, char **argv);

    // Get channel with a particular component name
    RLOG_DECL RLogChannel *GetComponentChannel(const char *component, 
	                             const char *path, 
				     LogLevel level = Log_Undef);

    // the global channel receives messages for all components
    RLOG_DECL RLogChannel *GetGlobalChannel( const char *path,
				   LogLevel level = Log_Undef);

#define DEF_CHANNEL(path,level) RLOG_CHANNEL_IMPL(RLOG_COMPONENT, path, level)
#define RLOG_CHANNEL(path) RLOG_CHANNEL_IMPL(RLOG_COMPONENT, path, rlog::Log_Undef)
#define RLOG_CHANNEL_IMPL(COMPONENT,path,level) \
    rlog::GetComponentChannel(STR(COMPONENT),path,level)

    /*
	Pre-defined channels, 
	&quot;debug&quot;, &quot;warning&quot;, and &quot;error&quot;.

	You can of course defined sub-channels based on the predefined types,
	such as &quot;debug/level1&quot;, or whatever.
    */
    extern RLOG_DECL RLogChannel *_RLDebugChannel;
    extern RLOG_DECL RLogChannel *_RLInfoChannel;
    extern RLOG_DECL RLogChannel *_RLWarningChannel;
    extern RLOG_DECL RLogChannel *_RLErrorChannel;
[...]
</code></pre>
<p>In der Header-Datei werden vordefinierte Channels für Debug-Messages bereitgestellt, die mit</p>
<blockquote>
<p>extern RLOG_DECL RLogChannel *_RLDebugChannel</p>
</blockquote>
<p>definiert werden. Das RLOG_DECL ist das Makro</p>
<blockquote>
<p>_declspec(dllexport)</p>
</blockquote>
<p>, das angibt, dass diese Variable im Namespace rlog exportiert werden soll.</p>
<p>In meinem eigenen Programm versuche ich nun, mittels der Logging-Lib Debug-Messages auszugeben. Dazu definiert die rlog-Lib Makros</p>
<blockquote>
<p>rDebug()</p>
</blockquote>
<p>, mit denen Strings auf stderr etc. ausgegeben werden können.<br />
rDebug ist ein Makro, das die Funktion</p>
<pre><code>_rMessage( LOGID, rlog::_RLDebugChannel, ##__VA_ARGS__ )
</code></pre>
<p>aufruft, die wiederum die Variable</p>
<pre><code>rlog::_RLDebugChannel
</code></pre>
<p>als Referenz braucht. Ich definiere deshalb in meinem Programmteil (der wiederum ne DLL ist):</p>
<pre><code>// RFIDWidget.cpp
#include &quot;rlog/rlog.h&quot;
#include &quot;rlog/RLogChannel.h&quot;
#include &quot;rlog/StdioNode.h&quot;

#include &lt;windows.h&gt;
#include &lt;winbase.h&gt;
#include &lt;QtGui&gt;
#include &lt;QtDebug&gt;
#include &quot;RFIDWidget.hpp&quot;

using namespace rlog;

extern StdioNode stdLog;
_declspec( dllimport ) rlog::RLogChannel *rlog::_RLDebugChannel;

[...]

RFIDWidget::RFIDWidget(QWidget* parent)
  : QWidget( parent )
{
  rDebug( &quot;RFIDWidget::RFIDWidget()&quot; );

  // setupUi(this);

  // connect( quitButton, SIGNAL(clicked()), this, SLOT( accept() ) );
  // connect( bindButton, SIGNAL( clicked() ), this, SLOT( on_bindButton_clicked() ) );
  // connect( openButton, SIGNAL( clicked() ), this, SLOT( on_openButton_clicked() ) );
  // connect( closeButton, SIGNAL( clicked() ), this, SLOT( on_closeButton_clicked() ) );

}
[...]
</code></pre>
<p>Leider bekomme ich, wenn ich den Debug Channel so deklariere mit</p>
<pre><code>_declspec( dllimport ) rlog::RLogChannel *rlog::_RLDebugChannel;
</code></pre>
<p>eine Warnung beim Kompilieren, dass eine inkonsistente DLL-Bindung vorliegt:</p>
<blockquote>
<p>warning C4273: 'rlog::_RLDebugChannel': Inkonsistente DLL-Bindung.<br />
d:\projekt\work\Tools\test\RFIDTestApp2\common\rlog/rlog.h(136): Siehe vorherige Definition von '_RLDebugChannel'</p>
</blockquote>
<p>Falls ich das</p>
<pre><code>_declspec (dllimport)
</code></pre>
<p>ändere in</p>
<pre><code>extern rlog::RLogChannel *rlog::_RLDebugChannel
</code></pre>
<p>, bekomme ich ein nicht aufgelöstes Symbol beim Linken.</p>
<p>Laut MSDN <a href="http://support.microsoft.com/?scid=kb%3Ben-us%3B90530&amp;x=3&amp;y=9" rel="nofollow">http://support.microsoft.com/?scid=kb%3Ben-us%3B90530&amp;x=3&amp;y=9</a> ist der Weg mit</p>
<pre><code>_declspec( dllimport)
</code></pre>
<p>korrekt beim Zugriff auf globale/Namespace-Variablen aus einer DLL. Deshalb meine Frage, wieso kommt der o.g. Fehler?</p>
<p>Bin für alle Hinweise dankbar,<br />
AlGaN</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/231009/dll-import-von-globalen-variablen</link><generator>RSS for Node</generator><lastBuildDate>Thu, 09 Apr 2026 18:47:41 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/231009.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 05 Jan 2009 13:40:53 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to DLL Import von globalen Variablen on Mon, 05 Jan 2009 13:40:53 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe ein Problem, eine globale Variable aus einem Namespace einer DLL in einem Modul (weitere DLL) zu importieren. Folgendes Szenario:</p>
<p>Ich will eine Logging-Library verwenden (rlog), die als DLL kompiliert einige Klassen und eben auch Variablen bereitstellt, die sich in einem Namespace befinden:</p>
<p>Header-File rlog.h:</p>
<pre><code>/*! @file rlog.h
  @brief Defines macros for debug, warning, and error messages.

*/

// may be useful for checking from configuration files
#define CURRENT_RLOG_VERSION 20040503
extern &quot;C&quot; int RLogVersion();

namespace rlog
{

    class RLogChannel;
    class RLogPublisher;
    class RLogNode;

    /*! @enum LogLevel
      Logging level definitions.
    */
    enum LogLevel
    {
	Log_Undef    =0, //!&lt; undefined level
	Log_Critical,    //!&lt; critical conditions
	Log_Error,       //!&lt; error conditions
	Log_Warning,     //!&lt; warning conditions
	Log_Notice,      //!&lt; normal, but significant, condition
	Log_Info,        //!&lt; informational
	Log_Debug        //!&lt; debug level messages
    };

    void RLOG_DECL RLogInit(int &amp;argc, char **argv);

    // Get channel with a particular component name
    RLOG_DECL RLogChannel *GetComponentChannel(const char *component, 
	                             const char *path, 
				     LogLevel level = Log_Undef);

    // the global channel receives messages for all components
    RLOG_DECL RLogChannel *GetGlobalChannel( const char *path,
				   LogLevel level = Log_Undef);

#define DEF_CHANNEL(path,level) RLOG_CHANNEL_IMPL(RLOG_COMPONENT, path, level)
#define RLOG_CHANNEL(path) RLOG_CHANNEL_IMPL(RLOG_COMPONENT, path, rlog::Log_Undef)
#define RLOG_CHANNEL_IMPL(COMPONENT,path,level) \
    rlog::GetComponentChannel(STR(COMPONENT),path,level)

    /*
	Pre-defined channels, 
	&quot;debug&quot;, &quot;warning&quot;, and &quot;error&quot;.

	You can of course defined sub-channels based on the predefined types,
	such as &quot;debug/level1&quot;, or whatever.
    */
    extern RLOG_DECL RLogChannel *_RLDebugChannel;
    extern RLOG_DECL RLogChannel *_RLInfoChannel;
    extern RLOG_DECL RLogChannel *_RLWarningChannel;
    extern RLOG_DECL RLogChannel *_RLErrorChannel;
[...]
</code></pre>
<p>In der Header-Datei werden vordefinierte Channels für Debug-Messages bereitgestellt, die mit</p>
<blockquote>
<p>extern RLOG_DECL RLogChannel *_RLDebugChannel</p>
</blockquote>
<p>definiert werden. Das RLOG_DECL ist das Makro</p>
<blockquote>
<p>_declspec(dllexport)</p>
</blockquote>
<p>, das angibt, dass diese Variable im Namespace rlog exportiert werden soll.</p>
<p>In meinem eigenen Programm versuche ich nun, mittels der Logging-Lib Debug-Messages auszugeben. Dazu definiert die rlog-Lib Makros</p>
<blockquote>
<p>rDebug()</p>
</blockquote>
<p>, mit denen Strings auf stderr etc. ausgegeben werden können.<br />
rDebug ist ein Makro, das die Funktion</p>
<pre><code>_rMessage( LOGID, rlog::_RLDebugChannel, ##__VA_ARGS__ )
</code></pre>
<p>aufruft, die wiederum die Variable</p>
<pre><code>rlog::_RLDebugChannel
</code></pre>
<p>als Referenz braucht. Ich definiere deshalb in meinem Programmteil (der wiederum ne DLL ist):</p>
<pre><code>// RFIDWidget.cpp
#include &quot;rlog/rlog.h&quot;
#include &quot;rlog/RLogChannel.h&quot;
#include &quot;rlog/StdioNode.h&quot;

#include &lt;windows.h&gt;
#include &lt;winbase.h&gt;
#include &lt;QtGui&gt;
#include &lt;QtDebug&gt;
#include &quot;RFIDWidget.hpp&quot;

using namespace rlog;

extern StdioNode stdLog;
_declspec( dllimport ) rlog::RLogChannel *rlog::_RLDebugChannel;

[...]

RFIDWidget::RFIDWidget(QWidget* parent)
  : QWidget( parent )
{
  rDebug( &quot;RFIDWidget::RFIDWidget()&quot; );

  // setupUi(this);

  // connect( quitButton, SIGNAL(clicked()), this, SLOT( accept() ) );
  // connect( bindButton, SIGNAL( clicked() ), this, SLOT( on_bindButton_clicked() ) );
  // connect( openButton, SIGNAL( clicked() ), this, SLOT( on_openButton_clicked() ) );
  // connect( closeButton, SIGNAL( clicked() ), this, SLOT( on_closeButton_clicked() ) );

}
[...]
</code></pre>
<p>Leider bekomme ich, wenn ich den Debug Channel so deklariere mit</p>
<pre><code>_declspec( dllimport ) rlog::RLogChannel *rlog::_RLDebugChannel;
</code></pre>
<p>eine Warnung beim Kompilieren, dass eine inkonsistente DLL-Bindung vorliegt:</p>
<blockquote>
<p>warning C4273: 'rlog::_RLDebugChannel': Inkonsistente DLL-Bindung.<br />
d:\projekt\work\Tools\test\RFIDTestApp2\common\rlog/rlog.h(136): Siehe vorherige Definition von '_RLDebugChannel'</p>
</blockquote>
<p>Falls ich das</p>
<pre><code>_declspec (dllimport)
</code></pre>
<p>ändere in</p>
<pre><code>extern rlog::RLogChannel *rlog::_RLDebugChannel
</code></pre>
<p>, bekomme ich ein nicht aufgelöstes Symbol beim Linken.</p>
<p>Laut MSDN <a href="http://support.microsoft.com/?scid=kb%3Ben-us%3B90530&amp;x=3&amp;y=9" rel="nofollow">http://support.microsoft.com/?scid=kb%3Ben-us%3B90530&amp;x=3&amp;y=9</a> ist der Weg mit</p>
<pre><code>_declspec( dllimport)
</code></pre>
<p>korrekt beim Zugriff auf globale/Namespace-Variablen aus einer DLL. Deshalb meine Frage, wieso kommt der o.g. Fehler?</p>
<p>Bin für alle Hinweise dankbar,<br />
AlGaN</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1639822</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1639822</guid><dc:creator><![CDATA[AlGaN]]></dc:creator><pubDate>Mon, 05 Jan 2009 13:40:53 GMT</pubDate></item><item><title><![CDATA[Reply to DLL Import von globalen Variablen on Mon, 05 Jan 2009 15:15:20 GMT]]></title><description><![CDATA[<p>richtig beantworten kann ich es nicht, nur hinweise geben. afaik macht man das an besten mit dllexport und dllimport. nutze doch den präprozessor.</p>
<pre><code class="language-cpp">#ifdef DLL_BUILD
#    define RLOG_DECL __declspec(dllexport)
#else
#    define RLOG_DECL __declspec(dllimport)
#endif
</code></pre>
<p>wird die variable korrekt exportiert? am besten &quot;depency walker&quot; mal nach schauen. ich dachte nämlich das das man nur variablen im globeln scope exportieren kann.</p>
<p>AlGaN schrieb:</p>
<blockquote>
<p>Falls ich das</p>
<pre><code>_declspec (dllimport)
</code></pre>
<p>ändere in</p>
<pre><code>extern rlog::RLogChannel *rlog::_RLDebugChannel
</code></pre>
<p>, bekomme ich ein nicht aufgelöstes Symbol beim Linken.</p>
</blockquote>
<p>rlog-Lib mitgelinkt <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/26a0.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--warning"
      title=":warning:"
      alt="⚠"
    /></p>
<p>AlGaN schrieb:</p>
<blockquote>
<p>eine Warnung beim Kompilieren, dass eine inkonsistente DLL-Bindung vorliegt:</p>
</blockquote>
<p><a href="http://forum.fachinformatiker.de/c-compiler-ides-apis/56410-inkonsistente-dll-bindung.html" rel="nofollow">http://forum.fachinformatiker.de/c-compiler-ides-apis/56410-inkonsistente-dll-bindung.html</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1639895</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1639895</guid><dc:creator><![CDATA[miller_m]]></dc:creator><pubDate>Mon, 05 Jan 2009 15:15:20 GMT</pubDate></item><item><title><![CDATA[Reply to DLL Import von globalen Variablen on Mon, 05 Jan 2009 15:40:43 GMT]]></title><description><![CDATA[<p>Hi miller_m,</p>
<p>danke für Deine Antwort. Mir ist gerade eben aufgefallen, dass in meinem eigenen Projekt (da ebenfalls DLL), auch ein</p>
<pre><code>#define _WINDLL
</code></pre>
<p>automatisch vom Qt-Buildsystem (qmake) erzeugt wird, weshalb in der rlog-Headerdatei</p>
<blockquote>
<p>common.h</p>
</blockquote>
<p>die Zeilen:</p>
<pre><code>#ifdef _WIN32
#  ifdef _WINDLL
#    define RLOG_DECL __declspec(dllexport)
#  else
#    define RLOG_DECL __declspec(dllimport)
#  endif // building/using DLL
#else // !_WIN32
#  define RLOG_DECL
#endif
</code></pre>
<p>das falsche __declspec( dllexport ) statt __declspec( dllimport ) deklariert wird. Nachdem ich das geändert habe, linkt alles einwandfrei <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Trotzdem danke nochmals,<br />
AlGaN</p>
<p>P.S.: Ich würde aber trotzdem gerne wissen, wie es mit der Exportierbarkeit globaler bzw. Variablen aus Namespaces aus DLLs bestellt ist? Falls mich da jemand aufklären könnte, wäre ich dankbar.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1639913</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1639913</guid><dc:creator><![CDATA[AlGaN]]></dc:creator><pubDate>Mon, 05 Jan 2009 15:40:43 GMT</pubDate></item><item><title><![CDATA[Reply to DLL Import von globalen Variablen on Mon, 05 Jan 2009 15:45:24 GMT]]></title><description><![CDATA[<p>AlGaN schrieb:</p>
<blockquote>
<p>P.S.: Ich würde aber trotzdem gerne wissen, wie es mit der Exportierbarkeit globaler bzw. Variablen aus Namespaces aus DLLs bestellt ist? Falls mich da jemand aufklären könnte, wäre ich dankbar.</p>
</blockquote>
<p>Ich würde tippen: Garnicht, oder zumindestens nur Compiler-/Compilerversionsbezogen.</p>
<p>Namensräume sind nicht im Einklang mit C, und DLL-Schnittstellen müssen C-Kompatibel sein um nicht abhängig von Compiler-/Compilerversion zu sein.</p>
<p>cu André</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1639915</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1639915</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Mon, 05 Jan 2009 15:45:24 GMT</pubDate></item><item><title><![CDATA[Reply to DLL Import von globalen Variablen on Tue, 06 Jan 2009 10:55:53 GMT]]></title><description><![CDATA[<p>Hallo asc,</p>
<p>danke für die Erklärung. Dass DLL-Schnittstellen C-kompatibel sein müssen, habe ich auch schon gelesen. In manchen Quellcodes sieht man deshalb ja, dass die __declspec-Deklarationen folgendermassen deklariert sind:</p>
<pre><code>#define MYLIBAPI extern &quot;C&quot; _ _declspec(dllexport)

#define MYLIBAPI extern &quot;C&quot; _ _declspec(dllimport)
</code></pre>
<p>(o.g. Zeilen stammen aus Jeffrey Richter - Programming Applications for Windows)</p>
<p>D.h. es wird explizit eine C-Schnittstelle exportiert. Allerdings gibt es auch Bibliotheken (wie das von mir verwendete rlog), bei denen das fehlt, d.h. sie exportieren wohl eine C++-Schnittstelle...</p>
<p>Mir geht auch nicht in den Kopf, wie sich die C-Kompatibilität mit Klassen verträgt, die exportiert werden müssen.</p>
<p>Sorry, wenn dass zu naiv klingt, hab bisher nicht so viel mit Windows-DLLs zu tun gehabt,</p>
<p>AlGaN</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1640308</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1640308</guid><dc:creator><![CDATA[AlGaN]]></dc:creator><pubDate>Tue, 06 Jan 2009 10:55:53 GMT</pubDate></item><item><title><![CDATA[Reply to DLL Import von globalen Variablen on Tue, 06 Jan 2009 11:41:20 GMT]]></title><description><![CDATA[<p>AlGaN schrieb:</p>
<blockquote>
<p>Mir geht auch nicht in den Kopf, wie sich die C-Kompatibilität mit Klassen verträgt, die exportiert werden müssen.</p>
</blockquote>
<p>Garnicht, zumindestens nicht ohne Kompatibilitätseinschränkungen je nach Compiler etc. zu haben. Es gibt Mittel und Wege auch Klassen Kompatibel zu machen (im Prinzip macht dies z.B. COM), dies schränkt die Programmierung aber ein, beziehungsweise man muss bei der Programmierung zusätzliche Regeln beachten (Ich gehe darauf jetzt aber nicht genauer ein, solche Ausflüge liegen bei mir schon ein Weilchen zurück).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1640329</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1640329</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Tue, 06 Jan 2009 11:41:20 GMT</pubDate></item></channel></rss>