3

我在使用 swig 在 PHP 中包装我的 c++ 类时遇到问题:我的类在头文件中声明如下:

#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);
};

这些方法中的每一个都包含几个函数。
我的接口文件如下:

%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"
%}    

我生成 Ccrypto.so 文件没有任何错误。但是当我在我的代码中使用这个类时,我遇到了这个错误:

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

当我检查 Ccrypto.php 文件时,我发现它class Ccrypto已经被声明了两次。我的意思是我有:

Abstract class Ccrypto {
....
}

class Ccrypto {
...
}

为什么 SWIG 会为我的班级生成两个声明?

4

1 回答 1

3

问题是您有一个与模块同名的类(%module或命令行上的 -module)。SWIG 将 C++ 中的自由函数公开为具有模块名称的抽象类的静态成员函数。这是为了模仿我认为的命名空间。因此生成的 PHP 将包含两个类,一个抽象类,如果你有一个与模块同名的类并且有任何非成员函数。

您可以使用以下方法进行测试:

%module test

%inline %{
class test {
};

void some_function() {
}
%}

这会产生您报告的错误。

在看到 PHP 运行时错误之前,SWIG 没有对此发出警告,这让我有点惊讶。在生成 Java 时,它会为同一接口提供以下错误:

类名不能等于模块类名:test

有几种可能的方法可以解决这个问题:

  1. 重命名模块
  2. 重命名代码库中的类。
  3. 重命名类(使用%rename):

    %module test
    
    %rename (test_renamed) test;
    
    %inline %{
    class test {
    };
    
    void some_function() {
    }
    %}
    
  4. 隐藏免费功能:

    %ignore some_function;
    
于 2012-09-16T14:56:24.973 回答