A23149577
A23149577

Reputation: 2155

SWIG fatal error: can not redeclare class

I have a problem with wrapping my c++ class in PHP using swig: my class is declared as below in header file:

#include <string.h>
using namespace std;
class Ccrypto
{
  int retVal;
public:
  int verify(string data, string pemSign, string pemCert);
  long checkCert(string inCert, string issuerCert, string inCRL);
  int verifyChain(string inCert, string inChainPath);
  int getCN(string inCert, string &outCN);
};

each of these methods consists of several functions.
My interface file is as below:

%module Ccrypto
%include <std_string.i>
%include "Ccrypto.h"
%include "PKI_APICommon.h"
%include "PKI_Certificate.h"
%include "PKI_Convert.h"
%include "PKI_CRL.h"
%include "PKI_TrustChain.h"

%{
#include "Ccrypto.h"

#include "PKI_APICommon.h"
#include "PKI_Certificate.h"
#include "PKI_Convert.h" 
#include "PKI_CRL.h"
#include "PKI_TrustChain.h"
%}    

I generate Ccrypto.so file without any error. But when I use this class inside my code I encounter this error:

Fatal error: Cannot redeclare class Ccrypto in /path/to/my/.php file

and when I checked the Ccrypto.php file I found out that class Ccryptohas been declared twice. I mean I have :

Abstract class Ccrypto {
....
}

and

class Ccrypto {
...
}

Why does SWIG generate two declarations for my class?

Upvotes: 3

Views: 631

Answers (1)

The problem is that you have a class with the same name as the module (%module or -module on the command line). SWIG exposes free functions in C++ as static member functions of an abstract class with the name of the module. This is intended to mimic namespaces I think. Thus the generated PHP will contain two classes, one abstract if you a class of the same name as the module and have any non-member functions.

You can test this out with:

%module test

%inline %{
class test {
};

void some_function() {
}
%}

Which produces the error you reported.

I'm slightly surprised that SWIG doesn't warn about this before the PHP runtime error is seen. It gives the following error for the same interface when generating Java:

Class name cannot be equal to module class name: test

There are a few possible ways you could work around this:

  1. Rename the module
  2. Rename the class in your code base.
  3. Rename the class (using %rename):

    %module test
    
    %rename (test_renamed) test;
    
    %inline %{
    class test {
    };
    
    void some_function() {
    }
    %}
    
  4. Hide the free function(s):

    %ignore some_function;
    

Upvotes: 3

Related Questions