<div class="gmail_quote">On 27 August 2012 11:28, Walter Bright <span dir="ltr"><<a href="mailto:newshound2@digitalmars.com" target="_blank">newshound2@digitalmars.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On 8/27/2012 1:08 AM, Manu wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br></blockquote></div><div class="im">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Also, I think it could be fixed so the scenario in the bug report worked as<br>
expected (I still don't understand why it did't work in the first place).<br>
</blockquote>
<br></div>
Because the two types were considered to be the same, only different.<br></blockquote><div><br></div><div>And how was that a problem? They never interacted in the example, the assignments were totally separate, they shouldn't have been confused.</div>
<div>Just speculating, but it just looks like the type was misrepresented when it was looked up from a map by name or something, and matched the wrong cached definition... or something along those lines.</div><div>It looks like a bug exposed from implementation detail, I can't see anything in the bug report that shouldn't theoretically work fine.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">------------------------------<u></u>----<br>
<br>
Please post a canonical example of how you use this, so we can think of an alternative.<br></blockquote><div><br></div><div><div>Well likewise, can you provide an example where, assuming that one bug were fixed, that the old approach actually caused a problem?</div>
</div><div>The bug report shows a situation that has a clear presumed behaviour, and could surely have just been fixed.</div><div><br></div><div><br></div><div><br></div><div><div>Almost all my API's are dynamically bound to foreign code, eg:</div>
<div><br></div><div>extern(C) void function( ref const(Vector2) v0, ref const(Vector2) v1, ref const(Vector2) v2, ref const(Color) color = Color.white, BlendMode blendMode = BlendMode.Disabled ) fillTriangle2D;</div><div>
extern(C) void function( ref const(Vector3) v0, ref const(Vector3) v1, ref const(Vector3) v2, ref const(Color) color = Color.white, BlendMode blendMode = BlendMode.Disabled ) fillTriangle;</div><div>extern(C) void function( ref const(Vector2) vPosition, ref const(Vector2) vSizeref, ref BaseTexture texture, ref const(Color) color = Color.white, BlendMode blendMode = BlendMode.Disabled, TextureMode textureMode = TextureMode.AllChannels ) fillSprite;</div>
<div>extern(C) void function( ref const(Vector2) vMin, ref const(Vector2) vMax, ref const(Color) color = Color.white, BlendMode blendMode = BlendMode.Disabled ) fillRectangle;</div><div>extern(C) void function( ref const(Vector3) vMin, ref const(Vector3) vMax, ref const(Matrix4x3) mLocalToWorld = Matrix4x3.identity, ref const(Color) color = Color.white, BlendMode blendMode = BlendMode.Disabled ) fillBox;</div>
<div>extern(C) void function( ref const(Vector3) vCenter, float fRadius, ref const(Matrix4x3) mLocalToWorld = Matrix4x3.identity, ref const(Color) color = Color.white, BlendMode blendMode = BlendMode.Disabled, int iTessellationX = 12, int iTessellationY = 8 ) fillSphere;</div>
<div>extern(C) void function( float fLength, float fRadius, ref const(Matrix4x3) mLocalToWorld = Matrix4x3.identity, ref const(Color) color = Color.white, BlendMode blendMode = BlendMode.Disabled, int iTessellation = 10 ) fillCone;</div>
<div>extern(C) void function( float fLength, float fRadius1, float fRadius2, ref const(Matrix4x3) mLocalToWorld = Matrix4x3.identity, ref const(Color) color = Color.white, BlendMode blendMode = BlendMode.Disabled, int iTessellation = 10 ) fillCylinder;</div>
<div>extern(C) void function( ref const(Matrix4) mClipToWorld, ref const(Color) color = Color.white, BlendMode blendMode = BlendMode.Disabled ) fillFrustum;</div></div><div><br></div><div><br></div><div>Functions in structs is common, default args are often convenient:</div>
<div><br></div><div><div>struct MFMaterialInterface</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>extern (C) int       function(void* pPlatformData) registerMaterial;</div><div><span class="Apple-tab-span" style="white-space:pre">     </span>extern (C) void      function() unregisterMaterial;</div>
<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">     </span>extern (C) void      function(MFMaterial* pMaterial, MFMaterialCreateParams *pCreateParams = null) createInstance;</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>extern (C) void      function(MFMaterial* pMaterial) destroyInstance;</div>
<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">     </span>extern (C) int       function() getNumParams;</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>extern (C) MFMaterialParameterInfo* function(int parameterIndex) getParameterInfo;</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span>extern (C) void      function(MFMaterial* pMaterial, int parameterIndex, int argIndex, size_t value) setParameter;</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>extern (C) size_t    function(MFMaterial* pMaterial, int parameterIndex, int argIndex, void* pValue = null) getParameter;</div>
<div>}</div><div><br></div><div>extern (C) void function(const(char)* pName, const(MFMaterialInterface)* pInterface) MFMaterial_RegisterMaterialType;</div></div><div><br></div><div>This isn't the best demonstration of this pattern, just a compact one. But function pointers in structs/classes is not unusual.</div>
<div><br></div><div><br></div><div><br></div><div>Here's an advanced trick I use a lot since D doesn't extern to static C++ methods (heavily simplified, this is way out of context):</div><div><br></div><div>struct CPPClass</div>
<div>{</div><div>    this()</div><div>    {</div><div>        // not my actual code, but effectively, write 'this' and the C++ method pointer into a delegate on initialisation [I wrap this process up using magic]</div>
<div>        void** pDelegate = cast(void**)&cppNonVirtualMethod;</div><div>        pDelegate[0] = this;</div><div><div>        pDelegate[1] = pCPPMethodPointer;</div></div><div>    }</div><div><br></div><div>    void delegate(int x = 0) cppNonVirtualMethod; // C++ methods often have default args</div>
<div><br></div><div>private:</div><div>    // C++ method pointer received from foreign code during initialisation</div><div>    static void* pCPPMethodPointer;</div><div>}</div><div><br></div></div>