Problem with coupling shared object symbol visibility with protection
Walter Bright via Digitalmars-d
digitalmars-d at puremagic.com
Wed Jan 28 03:00:12 PST 2015
On 1/27/2015 2:05 PM, Rainer Schuetze wrote:
>
>
> On 26.01.2015 23:24, Walter Bright wrote:
>>> The problem here is that you don't want to make someHelperFunc()
>>> export because that would mean users could call it directly, but
>>> you want it to be available for cross shared library calls. The
>>> cross shared library call happens if a template is instanced from a
>>> different shared library / executable than the module it was
>>> originally located in.
>>
>> exporting a template and then having the user instantiate outside of
>> the library doesn't make a whole lot of sense, because the
>> instantiation won't be there in the library. The library will have to
>> instantiate every use case. If the compiler knows the library
>> instantiated it, it won't re-instantiate it locally.
>
> The problem is not about into which binary the template is generated to (this
> must be the binary where it is used),
The example had marked the template itself as 'export'. This raises the specter
of which binary the template instantiation exists in.
> but how to access private non-templated methods called by the template.
>
> From the core.time.FracSec example:
>
> export struct FracSec
> {
> ///...
> static FracSec from(string units)(long value)
> if(units == "msecs" ||
> units == "usecs" ||
> units == "hnsecs" ||
> units == "nsecs")
> {
> immutable hnsecs = cast(int)convert!(units, "hnsecs")(value);
> _enforceValid(hnsecs);
> return FracSec(hnsecs);
> }
>
> private static void _enforceValid(int hnsecs)
> {
> if(!_valid(hnsecs))
> throw new TimeException("FracSec must ...");
> }
> ///...
> }
>
> _enforceValid() could also be a free function. It is likely to be compiled into
> druntime.dll, but needs to be exported from the DLL to be callable by the
> instantiation of the template function in another DLL. The "private" forbids
> exporting, though.
I tend to view a DLL's exports as being inherently not private, hence D's export
design being a "super" public. At the risk of sounding flip, I suggest simply
removing the 'private' from free functions one wishes to export. If the user is
calling undocumented functions that start with '_', we can presume they know
what they're doing.
If you still want to hide the free function, it can be done like this:
struct Bar(T) {
void callit() { Impl.freefunc(); }
}
private struct Impl {
export static void freefunc() { }
}
More information about the Digitalmars-d
mailing list