www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - PHP extension in D

reply "gedaiu" <szabobogdan yahoo.com> writes:
Hi,

I want to extend Php with an extension written in D, and wrap 
some D classes in php. My questions are:

1. How I can build a static library(I am using eclipse with ddt)
2. How I can create methods and create objects in c++ from the D 
library.


Thanks,
Bogdan
Apr 11 2013
next sibling parent Denis Shelomovskij <verylonglogin.reg gmail.com> writes:
11.04.2013 15:28, gedaiu пишет:
 Hi,

 I want to extend Php with an extension written in D, and wrap some D
 classes in php. My questions are:

 1. How I can build a static library(I am using eclipse with ddt)
 2. How I can create methods and create objects in c++ from the D library.

Post such questions to digitalmars.D.learn, please. -- Денис В. Шеломовский Denis V. Shelomovskij
Apr 11 2013
prev sibling next sibling parent =?UTF-8?B?IlLDqW15IE1vdcOremEi?= <firstname.name gmail.com> writes:
On Thursday, 11 April 2013 at 11:28:05 UTC, gedaiu wrote:
 Hi,

 I want to extend Php with an extension written in D, and wrap 
 some D classes in php. My questions are:

 1. How I can build a static library(I am using eclipse with ddt)
 2. How I can create methods and create objects in c++ from the 
 D library.


 Thanks,
 Bogdan

I once tried to make a proof of concept PHP extension in D on an Ubuntu Linux. I chose to make it "simple" by letting Swig (www.swig.org) do the heavy wrapping work for me. It's then becomes quite as much "difficult" as calling some D code from C. Below is an outline of the steps it took me to wrap a D function for PHP. You'll still have to figure out how to make it work nicely with Eclipse and on your particular platform, nonetheless it should help you getting started. Note that this approach could also be used to call some D code from Java, C# or any other language supported by Swig. 1. Write / get the D code (speedup.d).
 import std.stdio , std.string ; import std.conv : to;
 string speedUp (string msg) {
     writefln ("-- %s --", msg);
     return `sped up "%s"`.format (msg);
 }

2. make a C API for that code, declaring the functions of that API with the "extern (C)" qualifier.
 extern (C) {
     immutable (char) * d_speedUp (char * msg) {
         return toStringz (speedUp (to!string (msg)));
     }
 }

3. Create a Swig interface file for that C API (speedup.i). Also add a declaration to the "rt_init" function from the druntime.
 %module speedup
 char rt_init (long long);
 const char * d_speedUp (char * msg);

4. run Swig: `swig -php speedup.i`. This will generate several files: - speedup_wrap.c - php_speedup.h - speedup.php Now we've got to compile all those parts together: we want to generate a "speedup.so" dynamic library object from all that we got. 5. From what I researched, dmd (at least on Linux) needs to see a main function to properly generate all the code of the druntime within the dynamic library/shared object it generates. We will trick it by adding a fake main function (dfakemain.d):
 void main () {}

6. compile dfakemain.d:
 dmd -c dfakemain.d

7. compile speedup.o:
 dmd -fPIC -c -L-shared dfakemain.o speedup.d

8. compile speedup_wrap.o, you'll need to have everything needed to compile extension for PHP on your platform:
 gcc `php-config --includes` -fpic -c speedup_wrap.c

9. compile speedup.so, our target:
 dmd -shared speedup_wrap.o dfakemain.o speedup.o -ofspeedup.so

10. If everything went well so far, you can now try your extension within a script (dmd_speedup.php):
 <?php rt_init (0); // initialize the D runtime. echo d_speedUp 
 ("hello from php"), "\n";

You can launch the script with extension loading enabled with a command line such like this one:
 php -d enable_dl=1 -d extension=`pwd`/speedup.so dmd_speedup.php

It should then output:
 -- hello from php --
 sped up "hello from php"

Now, one could imagine to get a bit further by automating all that, like using the json output from dmd to generate a swig interface file and a nice OOP interface on the PHP side, but this would be much more work. Have fun!
Apr 11 2013
prev sibling next sibling parent "gedaiu" <szabobogdan yahoo.com> writes:
On Thursday, 11 April 2013 at 20:30:28 UTC, Rémy Mouëza wrote:
 On Thursday, 11 April 2013 at 11:28:05 UTC, gedaiu wrote:
 Hi,

 I want to extend Php with an extension written in D, and wrap 
 some D classes in php. My questions are:

 1. How I can build a static library(I am using eclipse with 
 ddt)
 2. How I can create methods and create objects in c++ from the 
 D library.


 Thanks,
 Bogdan

I once tried to make a proof of concept PHP extension in D on an Ubuntu Linux. I chose to make it "simple" by letting Swig (www.swig.org) do the heavy wrapping work for me. It's then becomes quite as much "difficult" as calling some D code from C. Below is an outline of the steps it took me to wrap a D function for PHP. You'll still have to figure out how to make it work nicely with Eclipse and on your particular platform, nonetheless it should help you getting started. Note that this approach could also be used to call some D code from Java, C# or any other language supported by Swig. 1. Write / get the D code (speedup.d).
 import std.stdio , std.string ; import std.conv : to;
 string speedUp (string msg) {
    writefln ("-- %s --", msg);
    return `sped up "%s"`.format (msg);
 }

2. make a C API for that code, declaring the functions of that API with the "extern (C)" qualifier.
 extern (C) {
    immutable (char) * d_speedUp (char * msg) {
        return toStringz (speedUp (to!string (msg)));
    }
 }

3. Create a Swig interface file for that C API (speedup.i). Also add a declaration to the "rt_init" function from the druntime.
 %module speedup
 char rt_init (long long);
 const char * d_speedUp (char * msg);

4. run Swig: `swig -php speedup.i`. This will generate several files: - speedup_wrap.c - php_speedup.h - speedup.php Now we've got to compile all those parts together: we want to generate a "speedup.so" dynamic library object from all that we got. 5. From what I researched, dmd (at least on Linux) needs to see a main function to properly generate all the code of the druntime within the dynamic library/shared object it generates. We will trick it by adding a fake main function (dfakemain.d):
 void main () {}

6. compile dfakemain.d:
 dmd -c dfakemain.d

7. compile speedup.o:
 dmd -fPIC -c -L-shared dfakemain.o speedup.d

8. compile speedup_wrap.o, you'll need to have everything needed to compile extension for PHP on your platform:
 gcc `php-config --includes` -fpic -c speedup_wrap.c

9. compile speedup.so, our target:
 dmd -shared speedup_wrap.o dfakemain.o speedup.o -ofspeedup.so

10. If everything went well so far, you can now try your extension within a script (dmd_speedup.php):
 <?php rt_init (0); // initialize the D runtime. echo d_speedUp 
 ("hello from php"), "\n";

You can launch the script with extension loading enabled with a command line such like this one:
 php -d enable_dl=1 -d extension=`pwd`/speedup.so 
 dmd_speedup.php

It should then output:
 -- hello from php --
 sped up "hello from php"

Now, one could imagine to get a bit further by automating all that, like using the json output from dmd to generate a swig interface file and a nice OOP interface on the PHP side, but this would be much more work. Have fun!

Rémy Mouëza Thanks a lot! Denis Shelomovskij sorry... this is my first post here, i will try to be careful next time when i post here next time..
Apr 11 2013
prev sibling next sibling parent "Pavel" <no spam.plz> writes:
Hello!

I've reproduced steps 1-9 on my Ubuntu 14.04 x64 machine, but now 
I have this errors:

root dlang:~/phpext# dmd -shared speedup_wrap.o dfakemain.o 
speedup.o -ofspeedup.so
/usr/bin/ld: 
/usr/lib/x86_64-linux-gnu/libphobos2.a(lifetime_485_6c8.o): 
relocation R_X86_64_32 against `_D15TypeInfo_Shared7__ClassZ' can 
not be used when making a shared object; recompile with -fPIC
/usr/lib/x86_64-linux-gnu/libphobos2.a: error adding symbols: Bad 
value
collect2: error: ld returned 1 exit status
--- errorlevel 1


I'm new to D/C languages, so what can I do to fix this error? I 
tried to compile with "-fPIC" option at all appropriate steps, 
but nothing helps :(
Jul 09 2014
prev sibling next sibling parent "Joakim" <dlang joakim.airpost.net> writes:
On Wednesday, 9 July 2014 at 21:30:45 UTC, Pavel wrote:
 Hello!

 I've reproduced steps 1-9 on my Ubuntu 14.04 x64 machine, but 
 now I have this errors:

 root dlang:~/phpext# dmd -shared speedup_wrap.o dfakemain.o 
 speedup.o -ofspeedup.so
 /usr/bin/ld: 
 /usr/lib/x86_64-linux-gnu/libphobos2.a(lifetime_485_6c8.o): 
 relocation R_X86_64_32 against `_D15TypeInfo_Shared7__ClassZ' 
 can not be used when making a shared object; recompile with 
 -fPIC
 /usr/lib/x86_64-linux-gnu/libphobos2.a: error adding symbols: 
 Bad value
 collect2: error: ld returned 1 exit status
 --- errorlevel 1


 I'm new to D/C languages, so what can I do to fix this error? I 
 tried to compile with "-fPIC" option at all appropriate steps, 
 but nothing helps :(

I think Rémy's advice is a little outdated when dealing with shared libraries, which are now supported on linux, so the fake main is not necessary there anymore: http://dlang.org/dll-linux.html#dso7 Try linking to phobos as a shared library as shown there and then calling the D function, I believe it should work (you'll also need to call rt_init() before the D library and rt_term() after).
Jul 09 2014
prev sibling next sibling parent "Pavel" <no spam.plz> writes:
On Wednesday, 9 July 2014 at 23:42:22 UTC, Joakim wrote:
 On Wednesday, 9 July 2014 at 21:30:45 UTC, Pavel wrote:
 Hello!

 I've reproduced steps 1-9 on my Ubuntu 14.04 x64 machine, but 
 now I have this errors:

 root dlang:~/phpext# dmd -shared speedup_wrap.o dfakemain.o 
 speedup.o -ofspeedup.so
 /usr/bin/ld: 
 /usr/lib/x86_64-linux-gnu/libphobos2.a(lifetime_485_6c8.o): 
 relocation R_X86_64_32 against `_D15TypeInfo_Shared7__ClassZ' 
 can not be used when making a shared object; recompile with 
 -fPIC
 /usr/lib/x86_64-linux-gnu/libphobos2.a: error adding symbols: 
 Bad value
 collect2: error: ld returned 1 exit status
 --- errorlevel 1


 I'm new to D/C languages, so what can I do to fix this error? 
 I tried to compile with "-fPIC" option at all appropriate 
 steps, but nothing helps :(

I think Rémy's advice is a little outdated when dealing with shared libraries, which are now supported on linux, so the fake main is not necessary there anymore: http://dlang.org/dll-linux.html#dso7 Try linking to phobos as a shared library as shown there and then calling the D function, I believe it should work (you'll also need to call rt_init() before the D library and rt_term() after).

Thank you very much for advice, it helped me :) Here is my build.sh file after all experiments: #!/bin/sh swig -php speedup.i dmd -m64 -fPIC -c -L-shared speedup.d sed -i "1i char* d_speedUp(char* arg1);" speedup_wrap.c gcc `php-config --includes` -fpic -c speedup_wrap.c dmd -m64 -shared -defaultlib=libphobos2.so -I/usr/lib/x86_64-linux-gnu speedup_wrap.o speedup.o -ofspeedup.so Note that we need to insert d_speedUp() function definition in speedup_wrap.c file, otherwise there will be a warning "cast to pointer" and segmentation fault when using compiled speedup.so file: speedup_wrap.c: In function ‘_wrap_d_speedUp’: speedup_wrap.c:1141:12: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] Also I found no mention about rt_term() method in generated files, so my php script works without it. result = (char *)d_speedUp(arg1);
Jul 10 2014
prev sibling next sibling parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Thursday, 10 July 2014 at 20:42:41 UTC, Pavel wrote:
 Thank you very much for advice, it helped me :) Here is my 
 build.sh file after all experiments:

 #!/bin/sh
 swig -php speedup.i
 dmd -m64 -fPIC -c -L-shared speedup.d
 sed -i "1i char* d_speedUp(char* arg1);" speedup_wrap.c
 gcc `php-config --includes` -fpic -c speedup_wrap.c
 dmd -m64 -shared -defaultlib=libphobos2.so 
 -I/usr/lib/x86_64-linux-gnu speedup_wrap.o speedup.o 
 -ofspeedup.so

 Note that we need to insert d_speedUp() function definition in 
 speedup_wrap.c file, otherwise there will be a warning "cast to 
 pointer" and segmentation fault when using compiled speedup.so 
 file:
 speedup_wrap.c: In function ‘_wrap_d_speedUp’:
 speedup_wrap.c:1141:12: warning: cast to pointer from integer 
 of different size [-Wint-to-pointer-cast]

 Also I found no mention about rt_term() method in generated 
 files, so my php script works without it.
    result = (char *)d_speedUp(arg1);

Great! This information might be valuable for others. If you want and have the time, maybe you can write a short how-to article for the wiki? http://wiki.dlang.org/Articles
Jul 10 2014
prev sibling parent "Pavel" <no spam.plz> writes:
Sure, I will write the how-to-do article, if I have plenty of 
time the next week. If not, I will write it later. All in all, 
the article soon will be ready.
Jul 11 2014