D2 __gshared and compatibility with D1

Mike Wey mike-wey at example.com
Sun Jan 24 10:55:49 PST 2010


On 01/24/2010 05:13 PM, Stanislav Blinov wrote:
> Hello,
>
> As some of you might know, there is a great package for D called
> Derelict (Derelict2 now actually). It provides bindings for several
> interesting C libraries like SDL, OpenGL and FreeType. The key point of
> Derelict is that it is designed to work exclusively with dynamic
> libraries. To achieve this, it provides a bunch of function pointers for
> every library, and these pointers are bound to function addresses when
> dynamic library is actually loaded. Simple example:
>
> extern(C) void function() someLibFunction;
>
> //...
> void main()
> {
> DerelictSomeLib.load(); // this call will load dynamic library and
> initialize someLibFunction
>
> someLibFunction();
>
> }
>
> Another key point of Derelict is compatibility with both D1 and D2. But
> for current D2, someLibFunction will be initialized only for the thread
> that called DerelictSomeLib.load(), because the pointer itself is
> thread-local, thus all other threads will also need to call
> DerelictSomeLib.load(), which looks like a gap in compatibility. So
> basically it would require to enclose function pointers in __gshared
> block, and here comes the problem: there is no __gshared in D1, so
> mixins should be used to keep compatibility.
>
> I proposed a solution which is based on 'templating' function pointers,
> that is, putting them into a parameterless template, and then mixing
> this template in like this:
>
> // for simplicity, no further version checking provided, but for
> // dmd we would also need to check compiler version here
> version (D_Version2)
> {
> mixin("__gshared { mixin FunctionPointers; }");
> }
> else
> {
> mixin FunctionPointers;
> }
>
> It works fine, but author and maintainer of Derelict is somewhat
> skeptical about templates (and thus he's against applying this
> solution), and actually I agree with him that this approach has a
> significant impact on compile times, especially for libraries with lots
> of functions like OpenGL.
>
> Is there some other way of __gshared'ing a set of data without breaking
> compatibility with D1? Current D2 syntax allows __gshared import, but it
> has no effect on imported module (and I don't think it should, seems
> more like an inconsistency to me).

With GtkD we define a function that returns an empty string or one 
containing __gshared depending on the dmd version, and then mixes that 
in with the function pointers, like so:

version(D_Version2)
{
	string gshared() { return "__gshared "; }
}
else
{
	char[] gshared() { return ""; }
}

mixin( gshared ~ "large string containing the function pointers" );

It does increase the compile time a little.

-- 
Mike Wey


More information about the Digitalmars-d-learn mailing list