I've written up a small howto on the subject and I can send it along if you 
like. The process described in the document works fine for PHP 4.0.6, 
although it's a little bit different for the 4.1.0RCs and the final. (There 
seemed to have been problems with the build process in 4.0.6 that made 
using C++ tricky.)

Basically, when I'm using C++ with PHP, I write the C++ classes and such 
and make an interface to PHP in C. Works pretty well for what I've done so 
far.

Here's the basic idea (at least for 4.0.6):

0. Use ext_skel to set things up. We'll call the new module "yourmodule".

1. Open up the config.m4 file created and fix things up like the following:

    PHP_ARG_ENABLE(yourmodule, whether to enable yourmodule support,
    [  --enable-yourmodule           Enable yourmodule support]
    )

    if test "$PHP_YOURMODULE" == "yes"; then
        PHP_EXTENSION(yourmodule, $ext_shared)
        PHP_REQUIRE_CXX()
    fi

2. Open up the Makefile.in file and set it up something like this:

    LTLIBRARY_NAME        = libyourmodule.la
    LTLIBRARY_SOURCES     = yourmodule.c
    LTLIBRARY_SOURCES_CPP = yourmodulecpp.cpp
    LTLIBRARY_SHARED_NAME = yourmodule.la
    LTLIBRARY_SHARED_LIBADD  = $(YOURMODULE_SHARED_LIBADD)
    LTLIBRARY_OBJECTS_X = yourmodulecpp.lo
    include $(top_srcdir)/build/dynlib.mk

yourmodule.c will have the stuff that talks to PHP, like the PHP_FUNCTION() 
calls an such.

yourmodulecpp.cpp will have all of the C++ stuff. It doesn't talk to PHP 
directly, it goes through yourmodule.c. (From what I can tell, you can't 
name them both yourmodule.c/cpp. Thinks break.)

3. Set up your C++ header file something like this:

    #ifndef __YOURMODULECPP_H__
    #define __YOURMODULECPP_H__

    #ifdef __cplusplus
    extern "C" {
    #endif
  
    #include <string>
 
    #ifdef __cplusplus
    } 
    #endif

    class MyClass
    {
        private:
            string itsString;

        public:
            MyClass(string);
            ~MyClass();

            const string getString();
            void setString(const string);
    };

    extern "C" const char* useClass(const char* incoming);

    #endif

So basically, wrap C++ stuff in extern "C". useClass() is just a simple 
function you can access from C. This example is of course extremely 
simplistic, but just as an example, it'll do. Plus, it'll show off the 
standard C++ string library, and if it works for you, then it'll prove that 
you've got C++ working with PHP.


4. Next, yourmodulecpp.cpp:

    #include "yourmodulecpp.h"

    MyClass::MyClass(string incoming)
    {
        itsString = incoming;
    }

    MyClass::~MyClass()
    {
        /* not much here, just a default destructor */
    }

    const string MyClass::getString()
    {
        return itsString;
    }

    void MyClass::setString(const string incoming)
    {
        itsString = incoming;
    }

    extern "C" const char* useClass(const char* incoming)
    {
        MyClass blah(incoming);
        return blah.getString().c_str();
    }

Again, very simple: useClass just takes in a C-like string, instantiates a 
MyClass object, calls the MyString::getString() function from the object 
and returns a C-like string.


5. php_yourmodule.h shouldn't have to be changed too much, if at all. 
yourmodule.c should include a PHP_FUNCTION() call something like this:

    PHP_FUNCTION(yourmodule)
    {
        pval **arg;

        if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == 
FAILURE) {
             WRONG_PARAM_COUNT;
        }

        convert_to_string_ex(arg);

        RETURN_STRING(useClass((*arg)->value.str.val), 1);
    }

So basically, take a string from PHP, convert it to a C-like string, pass 
it to the useClass() function where it will go through the MyClass object 
back in yourmodulecpp.cpp and go through the standard C++ string class, get 
returned to C as a C string, then get returned to PHP. Nothing much really 
happens, but if it all works, it'll prove C++ is working with C and PHP.


6. Run buildconf in the root PHP directory. When running configure, add a 
--enable-yourmodule argument. Run make clean and make. 

Now, in PHP 4.0.6, I had problems with the actual build process. 
Eventually, make could die and start spitting errors about not being able 
to find references to the functions in the standard C++ string library. 
This was to be expected, as the linking was being done by the linker using 
C semantics, not C++. 

To fix this, run the make until it dies. When it does, open up 
config_vars.mk in the PHP root directory and change the line that reads

    CC=gcc

to 

    CC=g++

and run make again. Everything should link now and you should be left with 
a useable php binary. PHP 4.1.0 doesn't seem to have this problem.

By running a script like:

   <?php print yourmodule("hello world"); ?>

you should come up with the output

   hello world

Of course, if this works, then the C++ extension worked and all is well.

Getting things to work with apache takes a bit more work, but it's similar 
to the config_vars.mk trick. When the Apache build process dies with errors 
similar to the CGI build, open up $APACHE_HOME/src/Makefile and make the 
same changes (CC=gcc to CC=g++) and run make again. Everything should link 
fine and you'll end up with a useable httpd binary.

This is a fairly simple example, but it's worked for me. I was able to get 
a few C++ classes I had working fine with PHP. (One of them I've offered up 
as a PHP extension, but after a bit of interest, I decided I had better 
port it to C just to make it a bit more accessible.)

Anyways, if this doesn't help, I can ship along my howto, it goes into a 
bit more detail. And if that doesn't work, let me know.

J




Lars Knudsen wrote:

> Hello everyone.
> 
> Can anybody tell me why I get an "Call to undefined function" when
> compiling a module using a C++ compiler (made a small test - it works fine
> when renaming the extension to *.c ... ).
> There are no make errors.  The *only* error is that PHP seams unable to
> find the function when compiled using C++.
> Isn't it possible to do C++ in PHP extensions?!?!?
> BTW:  I'm using gcc on a Linux RH7.2
> -thanx
> 
> mail:  [EMAIL PROTECTED]


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to