<?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[Funktionszeiger serialisieren]]></title><description><![CDATA[<p>Mir ist bekannt, wie man zur Laufzeit einen Funktionszeiger erstellt.<br />
Jetzt würde ich diesen Zeiger gerne serialisieren (= speichern). Da ich annehme, dass das Speichersegment von Fall zu Fall ein anderes sein wird, denke ich, dass man statt einer Speicheradresse den Namen der Funktion aabspeichern müsste, auf die dann zur Laufzeit verwiesen werden soll.</p>
<p>Beispiel: Ich habe folgenden Funktionszeiger:</p>
<pre><code>void (*pFunc)();
</code></pre>
<p>der verwiest auf Funktionen vom Typ:</p>
<pre><code>void SomeFunc(){};
</code></pre>
<p>Die Zuweisung sieht zur Laufzeit so aus:</p>
<pre><code>pFunc = SomeFunc;
</code></pre>
<p>und der Aufruf:</p>
<pre><code>(*pFunc)();
</code></pre>
<p>Das von SomeFunc belegte Speichersgemnet wird sich freilich ändern, so dass man nicht ein Speichersegment, sondern sinnvollerweise den Namen der Datei, &quot;SomeFunc&quot; speichern siollte.<br />
Aber wie lässt sich dieses char* Array zuück casten, so dass ich nicht den Namen der Datei, sondern das Speichersegment bekomme?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/224783/funktionszeiger-serialisieren</link><generator>RSS for Node</generator><lastBuildDate>Fri, 02 Oct 2026 04:20:24 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/224783.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 15 Oct 2008 06:50:31 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Funktionszeiger serialisieren on Wed, 15 Oct 2008 06:50:31 GMT]]></title><description><![CDATA[<p>Mir ist bekannt, wie man zur Laufzeit einen Funktionszeiger erstellt.<br />
Jetzt würde ich diesen Zeiger gerne serialisieren (= speichern). Da ich annehme, dass das Speichersegment von Fall zu Fall ein anderes sein wird, denke ich, dass man statt einer Speicheradresse den Namen der Funktion aabspeichern müsste, auf die dann zur Laufzeit verwiesen werden soll.</p>
<p>Beispiel: Ich habe folgenden Funktionszeiger:</p>
<pre><code>void (*pFunc)();
</code></pre>
<p>der verwiest auf Funktionen vom Typ:</p>
<pre><code>void SomeFunc(){};
</code></pre>
<p>Die Zuweisung sieht zur Laufzeit so aus:</p>
<pre><code>pFunc = SomeFunc;
</code></pre>
<p>und der Aufruf:</p>
<pre><code>(*pFunc)();
</code></pre>
<p>Das von SomeFunc belegte Speichersgemnet wird sich freilich ändern, so dass man nicht ein Speichersegment, sondern sinnvollerweise den Namen der Datei, &quot;SomeFunc&quot; speichern siollte.<br />
Aber wie lässt sich dieses char* Array zuück casten, so dass ich nicht den Namen der Datei, sondern das Speichersegment bekomme?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1599117</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1599117</guid><dc:creator><![CDATA[Percy2000]]></dc:creator><pubDate>Wed, 15 Oct 2008 06:50:31 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionszeiger serialisieren on Wed, 15 Oct 2008 07:06:08 GMT]]></title><description><![CDATA[<p>Schau Dir mal std::map an. Die Strings lassen sich allerdings nicht automatisch generieren. Du musst schon selbst jeder Funktion eine entsprechende Zuordnung zu einem String verpassen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1599120</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1599120</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Wed, 15 Oct 2008 07:06:08 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionszeiger serialisieren on Wed, 15 Oct 2008 07:15:16 GMT]]></title><description><![CDATA[<p>Leicht OT: Gibt es eigentlich in C++ eine schöne Abbildung von 1:1-Beziehungen ? In diesem Fall sollte ja nicht nur der key sondern auch der value eindeutig sein ...<br />
Kann man natürlich selbst bauen - aber vorgegeben gibt's das nicht, oder ?</p>
<p>Gruß,</p>
<p>Simon2.</p>
<p>P.S.: Außerdem fände ich eine map, deren operator[] auch eine &quot;not_found-Exception&quot; werfen kann, wünschenswert. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1599122</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1599122</guid><dc:creator><![CDATA[Simon2]]></dc:creator><pubDate>Wed, 15 Oct 2008 07:15:16 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionszeiger serialisieren on Wed, 15 Oct 2008 07:14:32 GMT]]></title><description><![CDATA[<p>Meiner meinung nach, sollten sihc die Adressen der Funktionen nicht ändern (auf jeden Fall nicht in Exe Dateien, bei dlls bin ich mir nicht sicher.<br />
Es sollte also ohne weiteres möglich sein, diese Abzuspeichern.<br />
Es kann natürlich sein, dass nach einem Rebuild nach minimalen Änderungen am Code, die abgespeicherte Adresse nicht mehr stimmt.</p>
<pre><code class="language-cpp">Code:
pFunc = SomeFunc;
</code></pre>
<p>Das speichern des Funktionspointers sieht aber so aus:</p>
<pre><code class="language-cpp">Code:
pFunc = &amp;SomeFunc;
</code></pre>
<p>Erlär doch mal wozu du das brauchst?<br />
Unter c++ gibt es viel bessere Konzepte: virutelle funktionen, Funktoren</p>
<p>Ich würd mal vermuten, das da ein schlechtes Design gewählt wurde.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1599124</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1599124</guid><dc:creator><![CDATA[vlad_tepesch]]></dc:creator><pubDate>Wed, 15 Oct 2008 07:14:32 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionszeiger serialisieren on Wed, 15 Oct 2008 07:18:18 GMT]]></title><description><![CDATA[<p>vlad_tepesch schrieb:</p>
<blockquote>
<p>Meiner meinung nach, sollten sihc die Adressen der Funktionen nicht ändern (auf jeden Fall nicht in Exe Dateien, bei dlls bin ich mir nicht sicher....</p>
</blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /><br />
Aber das Programm wird doch bei einem neuen Start höchstwahrscheinlich nicht an derselben Speicherstelle liegen, oder ?<br />
&quot;member function pointer&quot; tragen bestimmt nur &quot;relative Adressen&quot;, aber normale Funktionszeiger haben doch &quot;absolute Adressen&quot; ....</p>
<p>vlad_tepesch schrieb:</p>
<blockquote>
<p>...<br />
Das speichern des Funktionspointers sieht aber so aus:</p>
<pre><code class="language-cpp">Code:
pFunc = &amp;SomeFunc;
</code></pre>
<p>...</p>
</blockquote>
<p>Soweit ich weiß, ist aber Ersteres auch gültig.</p>
<p>Gruß,</p>
<p>Simon2.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1599126</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1599126</guid><dc:creator><![CDATA[Simon2]]></dc:creator><pubDate>Wed, 15 Oct 2008 07:18:18 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionszeiger serialisieren on Wed, 15 Oct 2008 07:25:54 GMT]]></title><description><![CDATA[<p>@Taychon<br />
das war sehr hilfreich.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1599135</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1599135</guid><dc:creator><![CDATA[Percy2000]]></dc:creator><pubDate>Wed, 15 Oct 2008 07:25:54 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionszeiger serialisieren on Wed, 15 Oct 2008 07:33:13 GMT]]></title><description><![CDATA[<p>@Taychon<br />
das war sehr hilfreich.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/734">@Simon</a> <a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/8482">@vlad</a><br />
- ja, es funktioniert auch ohne den Adressooperator. - Hintergrund der Serialisierung: es ist tatsächlich eine dll. Tatsächlich sollte ich versuchen, ob auch da eine absolute Adresse möglich ist - hab's in der Annahmme, dass sich da was ändert, noch gar nicht ausprobiert.</p>
<p>Wozu ich's brauche? In einer Datei werden Regelsätze gespeichert - im Sinne einer Grammatik -, die mit Funktionen verknüpft werden sollen.<br />
Schon aus Speicherplatzgründen wäre es mir natürlich sehr viel lieber, wenn man eine einzige long Variable statt eines langen char Arrays nutzen könnte.</p>
<p>Was wären die Alternativen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1599139</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1599139</guid><dc:creator><![CDATA[Percy2000]]></dc:creator><pubDate>Wed, 15 Oct 2008 07:33:13 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionszeiger serialisieren on Wed, 15 Oct 2008 08:07:39 GMT]]></title><description><![CDATA[<blockquote>
<p>Schon aus Speicherplatzgründen wäre es mir natürlich sehr viel lieber, wenn man eine einzige long Variable statt eines langen char Arrays nutzen könnte.</p>
<p>Was wären die Alternativen?</p>
</blockquote>
<p>Wenn du das alles per String identifizieren willst kaum etwas anderes, als dir das irgendwie zu indexieren und dann kannst du auch std::vector nutzen, anstatt die schwere map. (Allerdings kann ich mir kaum vorstellen, dass es auf das bisschen an Speicher drauf ankommt.. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /> )</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1599156</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1599156</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Wed, 15 Oct 2008 08:07:39 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionszeiger serialisieren on Wed, 15 Oct 2008 08:22:53 GMT]]></title><description><![CDATA[<p>Percy2000 schrieb:</p>
<blockquote>
<p>@Taychon<br />
das war sehr hilfreich.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/734">@Simon</a> <a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/8482">@vlad</a><br />
- ja, es funktioniert auch ohne den Adressooperator. - Hintergrund der Serialisierung: es ist tatsächlich eine dll. Tatsächlich sollte ich versuchen, ob auch da eine absolute Adresse möglich ist - hab's in der Annahmme, dass sich da was ändert, noch gar nicht ausprobiert.</p>
<p>Wozu ich's brauche? In einer Datei werden Regelsätze gespeichert - im Sinne einer Grammatik -, die mit Funktionen verknüpft werden sollen.<br />
Schon aus Speicherplatzgründen wäre es mir natürlich sehr viel lieber, wenn man eine einzige long Variable statt eines langen char Arrays nutzen könnte.</p>
<p>Was wären die Alternativen?</p>
</blockquote>
<p>Also, ich würde es immer über eine Character basierste Zuordungstabelle machen. Schon alleine aufgrund der Portabilität.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1599172</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1599172</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Wed, 15 Oct 2008 08:22:53 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionszeiger serialisieren on Wed, 15 Oct 2008 13:40:11 GMT]]></title><description><![CDATA[<p>vlad_tepesch schrieb:</p>
<blockquote>
<p>Unter c++ gibt es viel bessere Konzepte: virutelle funktionen, Funktoren</p>
</blockquote>
<p>Inwiefern diese Konzepte einen Ersatz für die Sprachunterstützung von Serialisierung darstellen sollen, erschließt sich mir nicht.</p>
<p>Percy2000 schrieb:</p>
<blockquote>
<p>Tatsächlich sollte ich versuchen, ob auch da eine absolute Adresse möglich ist - hab's in der Annahmme, dass sich da was ändert, noch gar nicht ausprobiert.</p>
</blockquote>
<p>Wenn du mit den Konsequenzen (nach jedem erneuten Link können sich die Adressen ändern, bei DLLs auch von Programmstart zu Programmstart) leben kannst, anders gesagt: wenn die Datei ohnehin nur für die Laufzeit des Programmes Gültigkeit behalten soll, dann geht das. Ansonsten ist so etwas dringend zu unterlassen.</p>
<p>Percy2000 schrieb:</p>
<blockquote>
<p>Was wären die Alternativen?</p>
</blockquote>
<p>Wenn es kein Standard-C++ sein muß:</p>
<pre><code class="language-cpp">#include &lt;vcl.h&gt; // C++Builder
#pragma hdrstop

class TAssociatedFunctions : public TObject
{
__published:
    static void foo (void) { ShowMessage (&quot;foo&quot;); }
    static void bar (void) { ShowMessage (&quot;bar&quot;); }
};

int main (void)
{
    void (*func) (void);
    void (*func2) (void);

    func = &amp;TAssociatedFunctions::foo;
    String funcname = TAssociatedFunctions::MethodName (func);
    func2 = reinterpret_cast &lt;void (*) (void)&gt; (
        TAssociatedFunctions::MethodAddress (funcname));
    func2 (); // zeigt &quot;foo&quot; an
}
</code></pre>
<p>Falls doch, dann bleibt dir wenig anderes als eine Zuordnungstabelle wie std::map &lt;std::string, void (*) (void)&gt;, die zum Programmstart gefüllt wird.</p>
<p>Percy2000 schrieb:</p>
<blockquote>
<p>Schon aus Speicherplatzgründen wäre es mir natürlich sehr viel lieber, wenn man eine einzige long Variable statt eines langen char Arrays nutzen könnte.</p>
</blockquote>
<p>Dann könntest du ja z.B. aus den Funktionsnamen einen Hash generieren.</p>
<p>Für die C++Builder-Lösung könnte das z.B. so aussehen:</p>
<pre><code class="language-cpp">#include &lt;vcl.h&gt;
#include &lt;map&gt;
#include &lt;cstddef&gt;
#pragma hdrstop

unsigned simpleHashFunc (const char* str)
{
    unsigned retval = 0;

    if (str)
        while (*str)
            retval = ((retval &lt;&lt; 3) | (retval &amp; 0x80000000) &gt;&gt; 29) ^ *(str++);
    return retval;
}

template &lt;class T, typename HashVal, HashVal (*HashFunc) (const char*)&gt;
    class MethodHashSerializer
{
private:
    std::map &lt;HashVal, String&gt; rainbow_table;

#pragma pack(push, 1)
    struct TMethodTableEntry
    {
        WORD        RecordLen;
        void*       Addr;
        ShortString Name;

    };
#pragma pack(pop)

public:
    MethodHashSerializer (void)
    {
        TMetaClass* mc = __classid (T);
        char* mtp = *reinterpret_cast &lt;char**&gt; (
            reinterpret_cast &lt;char*&gt; (mc) + vmtMethodTable);
        TMethodTableEntry* mte;
        UTF8String methodName;

        unsigned methodCount = *reinterpret_cast &lt;WORD*&gt; (mtp);
        mtp += sizeof (WORD);

        while (methodCount-- &gt; 0)
        {
            mte = reinterpret_cast &lt;TMethodTableEntry*&gt; (mtp);
            mtp += mte-&gt;RecordLen;

            methodName = UTF8String (mte-&gt;Name);
            rainbow_table[HashFunc (methodName.c_str ())] = methodName.c_str ();
        }
    }

    static HashVal serialize (void* addr)
    {
        UTF8String name = __classid (T)-&gt;MethodName (addr);
        return simpleHashFunc (name.c_str ());
    }
    void* unserialize (HashVal val)
    {
        std::map &lt;HashVal, String&gt;::const_iterator i
            = rainbow_table.find (val);
        if (i == rainbow_table.end ())
            return 0;
        return __classid (T)-&gt;MethodAddress (i-&gt;second);
    }
};

class TAssociatedFunctions : public TObject
{
__published:
    static void foo (void) { ShowMessage (&quot;foo&quot;); }
    static void bar (void) { ShowMessage (&quot;bar&quot;); }
};

int main (void)
{
    void (*func) (void);
    void (*func2) (void);

    MethodHashSerializer &lt;TAssociatedFunctions, unsigned, simpleHashFunc&gt; hs;

    func = &amp;TAssociatedFunctions::foo;
    unsigned funchash = hs.serialize (func);
    func2 = reinterpret_cast &lt;void (*) (void)&gt; (hs.unserialize (funchash));
    func2 (); // zeigt &quot;foo&quot; an
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1599198</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1599198</guid><dc:creator><![CDATA[audacia]]></dc:creator><pubDate>Wed, 15 Oct 2008 13:40:11 GMT</pubDate></item></channel></rss>