Skip to content

Create a static method for ambiguous overloaded constructor#150

Merged
Naum-PDFTron merged 1 commit intonext_releasefrom
naum/cap-747-SWIG-overloads-wrapper-3
Mar 25, 2025
Merged

Create a static method for ambiguous overloaded constructor#150
Naum-PDFTron merged 1 commit intonext_releasefrom
naum/cap-747-SWIG-overloads-wrapper-3

Conversation

@Naum-PDFTron
Copy link
Copy Markdown
Contributor

Description

SWIG has issues with C++ overloaded methods (and constructors) to target scripting languages like Python, PHP and Ruby, like:

class ObjectIdentifier
{
public:
    ObjectIdentifier(const Predefined in_oid_enum);
    ObjectIdentifier(const DigestAlgorithm::Type in_digest_algorithm_type);
    // etc.
};

Both constructors take integral as input and, when called from scripting language (Python, PHP, Ruby), which knows just for one Integer type, SWIG has no way to unambiguosly distinguish which constructor to call. Therefor, SWIG offers several options to overcome that:

  1. %rename the second overloaded method and call it from the script by new name, say FromDigestAlgorithm().
    It is fine for class method but not for constructor since one need an instance to call it and SWIG doesn't add a static prefix to call it as static. One need to create a dummy instance to call the instance method:

    ObjectIdentifier dummy();
    ObjectIdentifier oid = dummy.FromDigestAlgorithm(in_digest_algorithm_type);
    

    This way to go is rejected.

  2. %inline the second method by creating a global (non-class-related) static method to do the above (1.) job. In script it would be called like:

    ObjectIdentifier oid1 = ObjectIdentifierFromDigestAlgorithm(in_digest_algorithm_type);	// construct from `DigestAlgorithm::Type`
    

    This works, but may confuse the developer. Say, in a similar case one should create instance as:

    ObjectIdentifier oid1 = ObjectIdentifier(in_oid_enum);	// construct from Crypto::Predefined
    

    Developer doesn't need to know that it is a SWIG that dictates the API which may look confusing.

  3. %extend the ObjectIdentifier class (internally and locally to SWIG) with a static method that will call propper constructor:

    %extend pdftron::Crypto::ObjectIdentifier {
    	public:
    	static pdftron::Crypto::ObjectIdentifier* FromDigestAlgorithm(const DigestAlgorithm::Type in_digest_algorithm) {
    		return new pdftron::Crypto::ObjectIdentifier(in_digest_algorithm);
    	}
    }
    

    The developer could call:

    	ObjectIdentifier oid1 = ObjectIdentifier(in_oid_enum);	// construct from Crypto::Predefined
    	ObjectIdentifier oid2 = ObjectIdentifier.FromDigestAlgorithm(in_digest_algorithm_type);	// construct from `DigestAlgorithm::Type`
    

    This is acceptable solutuion. But there is one additional proposal...

  4. Could we have a static method for the first case too and let it look like:

    ObjectIdentifier oid1 = ObjectIdentifier.FromPredefined(in_oid_enum);	// construct from Crypto::Predefined
    ObjectIdentifier oid2 = ObjectIdentifier.FromDigestAlgorithm(in_digest_algorithm_type);	// construct from `DigestAlgorithm::Type`
    

    Or, generally, could we wrap all overloaded constructors (and methods) with this kind of extension?

    Q: What to do with customers that already use current API?
    A: They can continue as is is now, but with one note in the documentation: "Deprecated. Please use new notation ..."

  5. During Script/GenSwigWrappers.py run, there are several important products that are left in dark and that may be good to be uploaded somehow:

    PDFNetPython/PDFNetPython.cpp
    PDFNetPython/PDFNetPython.hpp
    PDFNetPython/PDFNetPython.py

    PDFNetPHP/PDFNetPHP.cpp
    PDFNetPHP/PDFNetPHP.php
    PDFNetPHP/php_PDFNetPHP.h

    PDFNetRuby/PDFNetRuby.cpp
    PDFNetRuby/PDFNetRuby.hpp

    PDFNet*/swig.log
    PDFNet*/swig.err.log

    SWIG log files hides lot of overloading and missing defs info which would be good to look if some doesn;t work.

Changelog entry

N/A

Jenkins Builds

Wrappers ...
... Python3 Windows https://jenkins.apryse.com/job/Wrappers Python3 Windows/job/naum%252Fcap-747-SWIG-overloads-wrapper-3/1/
... Windows32 https://jenkins.apryse.com/job/Wrappers Windows32/job/naum%252Fcap-747-SWIG-overloads-wrapper-3/1/

... Python3 Linux https://jenkins.apryse.com/job/Wrappers Python3 Linux/job/naum%252Fcap-747-SWIG-overloads-wrapper-3/1/
... Python3 Linux32 https://jenkins.apryse.com/job/Wrappers Python3 Linux32/job/naum%252Fcap-747-SWIG-overloads-wrapper-3/1/

... Python Arm64 https://jenkins.apryse.com/job/Wrappers Python3 Linux ARM64/job/naum%252Fcap-747-SWIG-overloads-wrapper-3/1/

... Python Alpine https://jenkins.apryse.com/job/Wrappers Python Alpine/job/naum%252Fcap-747-SWIG-overloads-wrapper-3/1/

... Mac https://jenkins.apryse.com/job/Wrappers Mac/job/naum%252Fcap-747-SWIG-overloads-wrapper-3/1/

... PHP Linux https://jenkins.apryse.com/job/Wrappers PHP Linux/job/naum%252Fcap-747-SWIG-overloads-wrapper-3/1/
... PHP Alpine https://jenkins.apryse.com/job/Wrappers PHP Alpine/job/naum%252Fcap-747-SWIG-overloads-wrapper-3/1/

... Ruby Alpine https://jenkins.apryse.com/job/Wrappers%20Ruby%20Alpine/job/naum%252Fcap-747-SWIG-overloads-wrapper-3/1/

More details in:

@Naum-PDFTron Naum-PDFTron requested a review from rchennafi March 25, 2025 11:03
@Naum-PDFTron Naum-PDFTron merged commit c4bc470 into next_release Mar 25, 2025
@Naum-PDFTron Naum-PDFTron deleted the naum/cap-747-SWIG-overloads-wrapper-3 branch March 25, 2025 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants