CopernicaMarketingSoftware / PHP-CPP

Library to build PHP extensions with C++

Home Page:http://www.php-cpp.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Namespace causes segfault

gtamas opened this issue · comments

This is how I use it:

 static Php::Extension extension("aspose_php", "1.0");

 Php::Namespace ns("AsposePhp");

 Php::Class<AsposeUtil> util("AsposeUtil");

 util.method<&AsposeUtil::getVersion>("getVersion", { });

 ns.add<AsposeUtil>("AsposeUtil");

extension.add(std::move(ns));

This compiles fine, but PHP execution fails with segmentation fault (core dumped).

<?php 

use AsposePhp\AsposeUtil;

echo AsposeUtil::getVersion(); ?>

However, if I don't add the same class to any namespace, it works fine.

@EmielBruijntjes
Any suggestion what to try here? I guess this is supposed to work. I'm using PHP 7.4 under Ubuntu latest.

Try registering the classes with a name like "Namespace\Classname"

@EmielBruijntjes
This is unfortunately not working

I tried

ns.add<AsposeUtil>("AsposePhp\\AsposeUtil");

and then in PHP:

<?php 

use AsposePhp\AsposeUtil; 
?>

Aspose.Slides version: <?php echo AsposePhp\AsposeUtil::getVersion(); ?>

But PHP cannot find the class this way:

Uncaught Error: Class 'AsposePhp\AsposeUtil' not found

I even tried to register the class in CPP this way:

Php::Class<AsposeUtil> util("AsposePhp\\AsposeUtil");

... resulting in the same error.

Try removing the enitre Php::Namespace variable. Add your class directly to the extension variable instead of to the ns variable.

UPDATE:

This works:

 Php::Class<AsposeUtil> util("AsposeUtil");
 ns.add<AsposePhp::AsposeUtil>(std::move(util));
 // this is also OK
//  ns.add(std::move(util)); 

However, this only works if I instantiate a class manually in PHP (i.e: new SomeClass(...)) or the class has static methods and I'm calling one of those.

When PHP is supposed to create the instance implicitly, it complains about missing class. For example:

<?php 
use AsposePhp\Presentation;
use AsposePhp\ISlideCollection;

 $pres = new Presentation(); // this works
 echo $pres->getSlides() // this fails because apparently ISlideCollection class  is unknown

This code runs only if the ISlideCollection class is not part of the namespace, but we just add it to the extension as you suggested.

extension.add(std::move(iSlideCol));

Strange.. I need to find a solution for this. For now I can use it as it is, but I must make this work with namespaces (even nested ones).

Try removing the enitre Php::Namespace variable. Add your class directly to the extension variable instead of to the ns variable.

 Php::Class<MyClass> myclass("MyNamespace\\MyClass");
extension.add(myclass);

Thanks! Yeah, that works.
But this approach also only works with explicitly used classes, the ones PHP creates fail (again, missing class error).

So

   Php::Class<AsposePhp::ISlideCollection> col("ISlideCollection"); // This is good
  Php::Class<AsposePhp::ISlideCollection> col("AsposePhp\\ISlideCollection");  This fails

The latter produces:

PHP Fatal error: Uncaught Error: Unknown class name ISlideCollection.

How do you instantiate it, dynamically?

Well, like this:

 $pres = new Presentation(); 
 echo $pres->getSlides() // This is supposed to return ISlideCollection instance.

However it works now. The error was in my CPP code:

 Php::Value Presentation::getSlides() {
        ISlideCollection* collection = new ISlideCollection(_slides);
        return Php::Object("ISlideCollection",collection); // The first parameter of this should be AsposePhp\\ISlideCollection...
    }

So I guess then it is solved. Thanks!

Try this

return Php::Object("NyNamespace\\ISlideCollection",collection);

Thanks Emiel!