<?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[C func-ptr to C++ std::function]]></title><description><![CDATA[<p>Guten Morgen Leute,</p>
<p>folgends, ich habe  eine c-lib mit eine &quot;callback&quot; funcptr.</p>
<pre><code class="language-cpp">typedef VOID(*fpUpdatePolygon)(stPolygon_t* const pPolygon, const stObject_t input);

void lib_register(fpUpdatePolygon fp);

</code></pre>
<p>wobei der callback innerhalb der c-lib invoked wird....</p>
<p>So nun habe ich eine C# Wrapper ,welcher folgendermaßen aussieht und auch funktioniert:</p>
<pre><code class="language-csharp">[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
           public delegate void fpUpdatePolygon(IntPtr polygon, DsmFieldStrategy.DsmFieldStrategyWrapper.stBuffer_t input);

           [DllImport(&quot;lib.dll&quot;, CallingConvention = CallingConvention.Cdecl)]
           public static extern void lib_register(fpUpdatePolygon fp);

       class foo
       {
           private fpUpdatePolygon _callback;

           private void UpdateNativePolygon(IntPtr pPolygon, stBuffer_t input)
           {
           ....... callback of pf
           }

           public foo()
           {
               _callback= new fpUpdatePolygon(UpdateNativePolygon);

               lib_register(_callback);
           }
       }

</code></pre>
<p>nun möchte ich das ganze auch in C++ machen:</p>
<pre><code class="language-cpp">class foo
{
	void UpdateNativePolygon(stPolygon_t* const pPolygon, const stObject_t input)
	{
		/* do something */
    }	

	const std::function&lt;void(stPolygon_t* const, const stObject_t)&gt; _callback;

public:

	foo()
		:_callback(std::bind(&amp;foo::UpdateNativePolygon, this, placeholders::_1, placeholders::_2))
	{

		auto fp = _callback.target&lt;fpUpdatePolygon&gt;();

		//_&gt; fp ist hier null???

		lib_register(fp);
	}
};
</code></pre>
<p>aber ich werd nicht schlau, liefert mir Target nicht den nativen funcptr? fp ist an de stelle null? ich dachte die interop. ist zwischen c und c++ besser als mit c# <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Was mache ich falsch?</p>
<p>danke euch</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/355117/c-func-ptr-to-c-std-function</link><generator>RSS for Node</generator><lastBuildDate>Tue, 18 Aug 2026 20:56:39 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/355117.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 28 Oct 2024 06:43:38 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to C func-ptr to C++ std::function on Mon, 28 Oct 2024 06:43:38 GMT]]></title><description><![CDATA[<p>Guten Morgen Leute,</p>
<p>folgends, ich habe  eine c-lib mit eine &quot;callback&quot; funcptr.</p>
<pre><code class="language-cpp">typedef VOID(*fpUpdatePolygon)(stPolygon_t* const pPolygon, const stObject_t input);

void lib_register(fpUpdatePolygon fp);

</code></pre>
<p>wobei der callback innerhalb der c-lib invoked wird....</p>
<p>So nun habe ich eine C# Wrapper ,welcher folgendermaßen aussieht und auch funktioniert:</p>
<pre><code class="language-csharp">[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
           public delegate void fpUpdatePolygon(IntPtr polygon, DsmFieldStrategy.DsmFieldStrategyWrapper.stBuffer_t input);

           [DllImport(&quot;lib.dll&quot;, CallingConvention = CallingConvention.Cdecl)]
           public static extern void lib_register(fpUpdatePolygon fp);

       class foo
       {
           private fpUpdatePolygon _callback;

           private void UpdateNativePolygon(IntPtr pPolygon, stBuffer_t input)
           {
           ....... callback of pf
           }

           public foo()
           {
               _callback= new fpUpdatePolygon(UpdateNativePolygon);

               lib_register(_callback);
           }
       }

</code></pre>
<p>nun möchte ich das ganze auch in C++ machen:</p>
<pre><code class="language-cpp">class foo
{
	void UpdateNativePolygon(stPolygon_t* const pPolygon, const stObject_t input)
	{
		/* do something */
    }	

	const std::function&lt;void(stPolygon_t* const, const stObject_t)&gt; _callback;

public:

	foo()
		:_callback(std::bind(&amp;foo::UpdateNativePolygon, this, placeholders::_1, placeholders::_2))
	{

		auto fp = _callback.target&lt;fpUpdatePolygon&gt;();

		//_&gt; fp ist hier null???

		lib_register(fp);
	}
};
</code></pre>
<p>aber ich werd nicht schlau, liefert mir Target nicht den nativen funcptr? fp ist an de stelle null? ich dachte die interop. ist zwischen c und c++ besser als mit c# <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Was mache ich falsch?</p>
<p>danke euch</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2622816</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2622816</guid><dc:creator><![CDATA[SoIntMan]]></dc:creator><pubDate>Mon, 28 Oct 2024 06:43:38 GMT</pubDate></item><item><title><![CDATA[Reply to C func-ptr to C++ std::function on Mon, 28 Oct 2024 07:25:20 GMT]]></title><description><![CDATA[<p>Man erhält bei <a href="https://en.cppreference.com/w/cpp/utility/functional/function/target" rel="nofollow">std::function&lt;R(Args...)&gt;::target</a> nur den als Template angegeben Typ zurück, wenn dieser auch genauso abgespeichert wurde:</p>
<blockquote>
<p>A pointer to the stored function if <code>target_type() == typeid(T)</code>, otherwise a null pointer.</p>
</blockquote>
<p>Es findet keine Konvertierung o.ä. statt, sondern dann wird einfach nur <code>null</code> zurückgegeben.<br />
Du musst schon einen C-Funktionszeiger verwenden (dann kannst du aber keine Memberfunktion angeben, außer diese ist <code>static</code>).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2622817</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2622817</guid><dc:creator><![CDATA[Th69]]></dc:creator><pubDate>Mon, 28 Oct 2024 07:25:20 GMT</pubDate></item><item><title><![CDATA[Reply to C func-ptr to C++ std::function on Mon, 28 Oct 2024 07:27:15 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/18594">@Th69</a> sagte in <a href="/forum/post/2622817">C func-ptr to C++ std::function</a>:</p>
<blockquote>
<p>Du musst schon einen C-Funktionszeiger verwenden (dann kannst du aber keine Memberfunktion angeben, außer diese ist static).</p>
</blockquote>
<p>hi, ja wenn ich die funktion static mache geht  es ,aber würde gern eine member funktion verwenden, gnau so wie im obigen c# wrapper da geht es ja wunderbar.</p>
<p>Gibt es keine möglichkeit ne member funktion auf den c fp zu casten/binden?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2622818</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2622818</guid><dc:creator><![CDATA[SoIntMan]]></dc:creator><pubDate>Mon, 28 Oct 2024 07:27:15 GMT</pubDate></item><item><title><![CDATA[Reply to C func-ptr to C++ std::function on Mon, 28 Oct 2024 07:46:16 GMT]]></title><description><![CDATA[<p>Nein, das geht bei C++ nicht. Bei einer nicht-statischen Memberfunktion wird immer implizit ein weiterer Parameter (<code>this</code>) erwartet.<br />
Da bei dir die C-Funktion keinen weiteren Parameter vom Typ <code>void*</code> verwendet, kann man nur globale Funktionen oder aber statische Memberfunktionen verwenden (ansonsten könnte man dann einen expliziten Cast benutzen).</p>
<p>In C# wird durch die explizite Angabe von <code>[UnmanagedFunctionPointer(...)]</code> sichergestellt, daß der <code>this</code>-Parameter intern nicht mitübergeben wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2622819</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2622819</guid><dc:creator><![CDATA[Th69]]></dc:creator><pubDate>Mon, 28 Oct 2024 07:46:16 GMT</pubDate></item><item><title><![CDATA[Reply to C func-ptr to C++ std::function on Mon, 28 Oct 2024 08:04:54 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/18594">@Th69</a> sagte in <a href="/forum/post/2622819">C func-ptr to C++ std::function</a>:</p>
<blockquote>
<p>Nein, das geht bei C++ nicht. Bei einer nicht-statischen Memberfunktion wird immer implizit ein weiterer Parameter (this) erwartet.<br />
Da bei dir die C-Funktion keinen weiteren Parameter vom Typ void* verwendet, kann man nur globale Funktionen oder aber statische Memberfunktionen verwenden (ansonsten könnte man dann einen expliziten Cast benutzen).<br />
In C# wird durch die explizite Angabe von [UnmanagedFunctionPointer(...)] sichergestellt, daß der this-Parameter intern nicht mitübergeben wird.</p>
</blockquote>
<p>ok verstehe, aber we bekommt c# dann hin dass der der native fp in ein c# member pt mit this gerelayed wird? wenn da geht, müsste es ja auch in c++ geht?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2622820</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2622820</guid><dc:creator><![CDATA[SoIntMan]]></dc:creator><pubDate>Mon, 28 Oct 2024 08:04:54 GMT</pubDate></item><item><title><![CDATA[Reply to C func-ptr to C++ std::function on Mon, 28 Oct 2024 09:32:51 GMT]]></title><description><![CDATA[<p>Das habe ich mir gedacht, daß jetzt diese Frage kommt. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";-)"
      alt="😉"
    /></p>
<p>Antwort: Mittels &quot;Compilermagie&quot;!<br />
So viel ich weiß (bzw. mal gelesen habe), erzeugt der C#-Compiler eine eigene Datenstruktur mit einem Zeiger (<code>IntPtr</code>) auf eine aus der Memberfunktion erzeugten neuen Funktion, wo die Zugriffe auf die Membervariablen dann auf diese Datenstruktur umgebogen sind. Und vor dem Aufruf werden dann diese Variablen aus den Membervariablen kopiert und nach dem Aufruf wieder zurückkopiert (Marshalling).</p>
<p>Gefunden habe ich dazu nur noch <a href="https://github.com/dotnet/csharplang/discussions/80" rel="nofollow">Proposal: C# should provide better interop with unmanaged function pointers</a> (von 2017), wo es darum ging, daß C# direkt C-Funktionzeiger unterstützen soll (ohne Marshalling), was auch jetzt seit C# 9 (<a href="https://dev.to/theramoliya/c-function-pointers-for-high-performance-scenarios-8l3" rel="nofollow">C# - Function Pointers for High-Performance Scenarios </a>) möglich ist.</p>
<p>Das ist der Vorteil von Sprachen mit Reflection bzw. dynamischer Codererzeugung (wobei ich nicht genau weiß, ob dies direkt beim Compilieren oder aber einmalig zur Laufzeit erzeugt wird).<br />
Dies ginge sicherlich auch mit C++, aber bisher unterscheidet C++ eben streng zwischen Funktionszeigern (<code>R (*)(...)</code>) und Memberfunktionszeigern (<code>R (C::*)(...)</code>).<br />
Dafür bräuchte man wohl dann ein eigenes Schlüsselwort - und außerdem setzt C++ (wie C) auf hohe Performance. <code>std::function&lt;...&gt;</code> ist dabei ein Kompromiss um einen Datentyp zu haben, welcher beides unterstützt - aber eben keine Konvertierung ermöglicht.</p>
<p>Wenn du es bei C# mal genauer wissen willst, dann könntest du einen C# Compiler wie <a href="https://sharplab.io/" rel="nofollow">SharpLab</a> benutzen und dir den generierten Code bzw. IL-Code anschauen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2622821</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2622821</guid><dc:creator><![CDATA[Th69]]></dc:creator><pubDate>Mon, 28 Oct 2024 09:32:51 GMT</pubDate></item><item><title><![CDATA[Reply to C func-ptr to C++ std::function on Mon, 28 Oct 2024 09:35:47 GMT]]></title><description><![CDATA[<p>Könnte man eventuell was mit lambdas machen, welche den &quot;this&quot; Pointer capturen um dann instanz methoden aufrufen zu können.<br />
Oder ist eine lambda nicht kompatibel zu einem funktions-pointer?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2622822</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2622822</guid><dc:creator><![CDATA[firefly]]></dc:creator><pubDate>Mon, 28 Oct 2024 09:35:47 GMT</pubDate></item><item><title><![CDATA[Reply to C func-ptr to C++ std::function on Mon, 28 Oct 2024 09:38:31 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/1725">@firefly</a></p>
<p>Lambdas gehen nur ohne Capture <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2622823</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2622823</guid><dc:creator><![CDATA[Schlangenmensch]]></dc:creator><pubDate>Mon, 28 Oct 2024 09:38:31 GMT</pubDate></item><item><title><![CDATA[Reply to C func-ptr to C++ std::function on Mon, 28 Oct 2024 10:00:00 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/20667">@Schlangenmensch</a> sagte in <a href="/forum/post/2622823">C func-ptr to C++ std::function</a>:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/1725">@firefly</a></p>
<p>Lambdas gehen nur ohne Capture <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
</blockquote>
<p>Schade. Hätte ja sein können das ein lambda mit capture auch kompatible zu einem funktion pointer wäre</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2622824</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2622824</guid><dc:creator><![CDATA[firefly]]></dc:creator><pubDate>Mon, 28 Oct 2024 10:00:00 GMT</pubDate></item><item><title><![CDATA[Reply to C func-ptr to C++ std::function on Mon, 28 Oct 2024 10:07:43 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/18594">@Th69</a> sagte in <a href="/forum/post/2622821">C func-ptr to C++ std::function</a>:</p>
<blockquote>
<p>Das habe ich mir gedacht, daß jetzt diese Frage kommt.<br />
Antwort: Mittels &quot;Compilermagie&quot;!<br />
So viel ich weiß (bzw. mal gelesen habe), erzeugt der C#-Compiler eine eigene Datenstruktur mit einem Zeiger (IntPtr) auf eine aus der Memberfunktion erzeugten neuen Funktion, wo die Zugriffe auf die Membervariablen dann auf diese Datenstruktur umgebogen sind. Und vor dem Aufruf werden dann diese Variablen aus den Membervariablen kopiert und nach dem Aufruf wieder zurückkopiert (Marshalling).<br />
Gefunden habe ich dazu nur noch Proposal: C# should provide better interop with unmanaged function pointers (von 2017), wo es darum ging, daß C# direkt C-Funktionzeiger unterstützen soll (ohne Marshalling), was auch jetzt seit C# 9 (C# - Function Pointers for High-Performance Scenarios ) möglich ist.<br />
Das ist der Vorteil von Sprachen mit Reflection bzw. dynamischer Codererzeugung (wobei ich nicht genau weiß, ob dies direkt beim Compilieren oder aber einmalig zur Laufzeit erzeugt wird).<br />
Dies ginge sicherlich auch mit C++, aber bisher unterscheidet C++ eben streng zwischen Funktionszeigern (R (<em>)(...)) und Memberfunktionszeigern (R (C::</em>)(...)).<br />
Dafür bräuchte man wohl dann ein eigenes Schlüsselwort - und außerdem setzt C++ (wie C) auf hohe Performance. std::function&lt;...&gt; ist dabei ein Kompromiss um einen Datentyp zu haben, welcher beides unterstützt - aber eben keine Konvertierung ermöglicht.<br />
Wenn du es bei C# mal genauer wissen willst, dann könntest du einen C# Compiler wie SharpLab benutzen und dir den generierten Code bzw. IL-Code anschauen.</p>
</blockquote>
<p>erstmal &quot;Chapeau&quot;, was du so ausm stehgreif weißt;)</p>
<p>zum glück habe ich die c- codebase in der hand.. ich werde jetzt dem callback ein &quot;context/tag&quot; void* mit geben.</p>
<pre><code class="language-cpp">
lib_register(this,callback)

</code></pre>
<p>dann geht das auch so;)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2622825</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2622825</guid><dc:creator><![CDATA[SoIntMan]]></dc:creator><pubDate>Mon, 28 Oct 2024 10:07:43 GMT</pubDate></item></channel></rss>