Another approach is based on the D's system of class's hierarchy:
all objects inherits explicitly or implicitly the Object.
So the idea is to implement OuterClass with pimpl, generate corresponding
di-file, manually remove all definitions of OuterClassPrivate from di-file
and change declaration of the pimpl-member.
For example:
first version of the shared library
module pimpl.mylib;
class PimplTest
{
this()
{
mImpl = new PimplTestPrivate();
}
~this()
{
}
string sayWhat(string what)
{
return mImpl.ku ~ " " ~ what;
}
private class PimplTestPrivate
{
string ku = "Ku!!1";
}
private PimplTestPrivate mImpl;
}
test application:
module main;
import std.stdio;
import pimpl.mylib;
void main()
{
PimplTest t = new PimplTest();
writeln(t.sayWhat("?"));
}
Shared mylib may be built the following way (under Linux):
$ dmd -H -c mylib.d -fPIC
$ dmd -ofmylib.so mylib.o -shared -defaultlib=libphobos2.so -L-rpath=/path/to/where/shared/phobos/library/is
Then edit genereated di-file:
// D import file generated from 'mylib.d'
module pimpl.mylib;
class PimplTest
{
this();
~this();
string sayWhat(string what);
// NOTE this
private Object mImpl;
}
Compile the test itsel
$ dmd -c main.d /path/to/first/version/of/mylib.di
$ ln -s /path/to/first/version/of/mylib.so .
$ dmd main.o -L-l:mylib.so -defaultlib=libphobos2.so -L-rpath=/path/to/where/shared/phobos/library/is:.
$ ./main
Say: ?
Then we change mylib:
module pimpl.mylib;
import std.conv;
class PimplTest
{
this()
{
mImpl = new PimplTestPrivate();
}
~this()
{
}
string sayWhat(string what)
{
return mImpl.getMessage1(mImpl.getValue(), what);
}
private class PimplTestPrivate
{
int getValue()
{
return 42;
}
string ku = "Ku!!1";
string getMessage1(int x, string y)
{
return "x = " ~ to!(string)(x) ~ ", " ~ y;
}
double pi = 22.0/7.0;
}
private PimplTestPrivate mImpl;
}
Compile it and replace binary shared object (so file) of the first version of mylib with just built one. Running test application must not crash but the output will be different.