[cffi-devel] Interface problem in LispWorks but not in SBCL

Sascha Van Cauwelaert sascha.vancauwelaert at gmail.com
Sat Nov 26 13:56:10 UTC 2011


Well, at first, I didn't want to bother people with the details. But now, it seems that it is needed.

The definition of the class and the implementation are below. Here is a git repo on which one can find the whole project : git://github.com/ggutierrez/cprelmaster.git
(the class is defined in rel/grelation.hh)

In my experience with SWIG and CFFI, I've never had that kind of problem. At some point, the implementation is using a library named cudd (http://vlsi.colorado.edu/~fabio/CUDD/). Maybe the problem comes from there, I really don't know.

Thank you you for any help, it is highly appreciated. 

Sascha

class GRelation {
  private:
    friend class GRelationIter;
    typedef boost::shared_ptr<VarImpl::RelationImpl> Impl;
    Impl pimpl_; ///> Relation storage
    /// Avoid default construction
    GRelation(void);
    /// Constructor taking an implementation
    explicit GRelation(Impl impl);
  public:
    /// \name Constructors, destructors and assignement
    //@{
    /// Constructor for an empty relation of arity \a a
    explicit GRelation(int a);
    /// Copy constructor
    GRelation(const GRelation& r);
    /// Assignment
    GRelation& operator=(GRelation& right);
    void become(const GRelation& other);

    /// Destructor
    ~GRelation(void);
    /// Constructs the relation \f$R=\mathcal{U}_{a}\f$
    static GRelation create_full(int a);
    //@}
    /// \name Modification operations
    //@{
    /**
     * \brief Adds tuple \a t to the relation. If \f$ t \in this \f$ the relation
     * remains unchanged.
     */
    void add(const Tuple& t);
    /**
     * \brief Adds the tuples contained in \a s to the relation.
     */
    void add(const std::vector<Tuple>& s);
    /**
     * \brief Union of relations: \f$ this = this \cup r \f$.
     */
    void unionAssign(const GRelation& r);
    /**
     * \brief Difference of relations: \f$ this = this \setminus r \f$.
     */
    void differenceAssign(const GRelation& r);
    //@}
    /// \name Set operations
    //@{
    /// Computes \f$ this \setminus r \f$
    GRelation difference(const GRelation& r) const;
    /// Computes \f$ this \cap r \f$
    GRelation intersect(const GRelation& r) const;
    /// Computes \f$ this \cup r \f$
    GRelation Union(const GRelation& r) const;
    /// Computes \f$ \overline{this}\f$
    GRelation complement(void) const;
    //@}
    /// \name Column permutation
    //@{
    /**
     * \brief Computes the permutation of \a this according to \a desc.
     *
     * \warning The permutation descriptor has to be valid for the relation. If it
     * is not then a InvalidPermDescriptor exception is thrown.
     */
    GRelation permute(const std::vector<std::pair<int,int>>& desc) const;
    /**
     * \brief Computes the permutation of \a this according to \a desc.
     *
     * \warning The permutation descriptor has to be valid for the relation. If it
     * is not then a InvalidPermDescriptor exception is thrown.
     */
    GRelation permute(const PermDescriptor& desc) const;
    /**
     * \brief Computes the relation resulting by shifting all the columns in \a r
     * \a n possitions to the right.
     *
     * The first \a n columns of \a r does not appear in the final relation.
     */
    GRelation shiftRight(int n) const;
    //@}
    /// \name Cross product
    //@{
    /**
     * \brief Computes \f$ \mathcal{U}_n \times this\f$.
     */
    GRelation timesULeft(int n) const;
    /**
     * \brief Computes \f$ this \times \mathcal{U}_n \f$.
     */
    GRelation timesURight(int n) const;
    /**
     * \brief Computes \f$ this \times r \f$
     */
    GRelation times(const GRelation& r) const;
    //@}
    /// \name Relational algebra operations
    //@{
    /**
     * \brief Returns: \f$ \mathit{this}\;\bowtie_{j}\; r \f$.
     *
     * This is, the result of joining the two relations on the \a j right most
     * columns of \a this and the \a j left most columns of \a r.
     */
    GRelation join(int j,const GRelation& r) const;
    /**
     * \brief Returns: \f$ \mathit{this}_{\smile_{f}}r \f$.
     *
     * \todo documentation
     */
    GRelation follow(int f,const GRelation& r) const;     
    /**
     * \brief Returns: \f$ \Pi_{p} this \f$.
     *
     * This is, the projection of \a this on the \a p rightmost columns.
     *
     * \warning Throws an exception InvalidProjection if \a p is not a valid column
     * in the relation.
     */
    GRelation project(int p) const;
    //@}
    /// \name Quantification
    //@{
    /**
     * \brief Returns the relation resulting from existencially quantifying on
     * column \a c
     *
     * \param c a column: \f$ 0 \leq c < \text{arity}(\text{this})\f$
     */
    GRelation exists(int c) const;
    /**
     * \brief Returns the relation resulting from uniquely quantifying on column
     * \a c
     *
     * \param c a column: \f$ 0 \leq c < \text{arity}(\text{this})\f$
     */
    GRelation unique(int c) const;
    /**
     * \brief Returns the relation resulting from uniquely quantifying on all the
     * columns in \a c.
     *
     * \param c a vector of columns: \f$ \forall_{i \in
     * \{0,\ldots,\text{size}(c)-1\}}: 0 \leq c[i] <
     * \text{arity}(\text{this})\f$
     */
    GRelation unique(const std::vector<int>& c) const;
    /**
     * \brief Returns the relation resulting from universaly quantifying on column
     * \a c
     *
     * \param c a column: \f$ 0 \leq c < \text{arity}(\text{this})\f$
     */
    GRelation forall(int c) const;
    //@}

    /**
     * \brief Computes the relation resulting by shifting all the columns in \a r
     * \a n possitions to the left.
     *
     * The new columns in the resulting relation are existentially quantified.
     */
    //GRelation shiftLeft(int n) const;
    /// Returns the relation \f$ this \times r \f$
    //@}
    /// \name Test operations
    //@{
    /// Tests \f$ this \subseteq r \f$
    bool subsetEq(const GRelation& r) const;
    /// Tests \f$ this \supset r \f$
    bool superset(const GRelation& r) const;
    /// Tests \f$ this \cap r = \emptyset \f$
    bool disjoint(const GRelation& r) const;
    /// Tests whether this represents the same relation as \a r
    bool eq(const GRelation& r) const;
    /// Tests whther the relation is empty
    bool empty(void) const;
    /// Tests whther the relation represents the universe
    bool universe(void) const;
    //@}
    /// \name Relation information
    //@{
    /// Returns the arity (i.e. number of columns) of the relation
    int arity(void) const;
    /// Returns the cardinality (i.e. number of tuples) of the relation
    double cardinality(void) const;
    //@}
    /// \name Constant relations
    //@{
    /// Creates the binary relation \f$ R = \{(x,y) : x = y \} \f$
    //static GRelation equalXY(void);
    //@}
    /// \name Content access
    //@{
    /**
     * \brief Returns one tuple represented by the relation.
     *
     * The only guarantee on the returned tuple is that it belongs to
     * the relation.
     */
    Tuple pickOneTuple(void) const;
    //@} 
    /// \name Output
    //{@
    void print(std::ostream& os) const;
    //@}
  };


  GRelation::GRelation(Impl impl)
    : pimpl_(impl) {}

  GRelation::GRelation(int a)
    : pimpl_(Impl(new RelationImpl(a)))
  {}

  GRelation::GRelation(const GRelation &r)
    : pimpl_(new RelationImpl(*(r.pimpl_))) { }

  GRelation& GRelation::operator =(GRelation& right) {
    pimpl_.swap(right.pimpl_);
    return *this;
  }

  void GRelation::become(const GRelation& other) {
    pimpl_ = Impl(new RelationImpl(*(other.pimpl_)));
  }

  GRelation::~GRelation(void) {}

  GRelation GRelation::create_full(int a) {
    RelationImpl full = RelationImpl::create_full(a);
    return
      GRelation(
		Impl(new RelationImpl(full))
		);
  }

  /*
   * Modification
   */ 
  void GRelation::add(const Tuple &t) {
    pimpl_->add(t);
  }

  void GRelation::add(const std::vector<Tuple>& s) {
    std::for_each(s.begin(), s.end(),
		  [=](const Tuple& t) { pimpl_->add(t); });
  }

  void GRelation::unionAssign(const GRelation &r) {
    pimpl_->add(*(r.pimpl_));
  }

  void GRelation::differenceAssign(const GRelation &r) {
    pimpl_->remove(*(r.pimpl_));
  }

  /*
   * Set operations
   */ 
  GRelation GRelation::difference(const GRelation &r) const {
    return
      GRelation(
		Impl(new RelationImpl(VarImpl::difference(*pimpl_,*(r.pimpl_))))
		);
  }

  GRelation GRelation::intersect(const GRelation &r) const {
    return
      GRelation(
		Impl(new RelationImpl(VarImpl::intersect(*pimpl_,*(r.pimpl_))))
		);
  }

  GRelation GRelation::Union(const GRelation &r) const {
    return
      GRelation(
		Impl(new RelationImpl(VarImpl::Union(*pimpl_,*(r.pimpl_))))
		);
  }

  GRelation GRelation::complement(void) const {
    return
      GRelation(
		Impl(new RelationImpl(VarImpl::complement(*pimpl_)))
		);
  }

  /*
   * Column permutation
   */ 
  GRelation GRelation::permute(const std::vector<std::pair<int,int>>& desc) const {
    return
      GRelation(
		Impl(new RelationImpl(pimpl_->permute(desc)))
		);
  }

  GRelation GRelation::permute(const PermDescriptor& desc) const {
    typedef boost::error_info<struct tag_perm_descriptor,std::string>
      perm_descriptor;
    
    if (!desc.valid(arity()))
      throw InvalidPermDescriptor()
	<< errno_code(errno)
	<< perm_descriptor("Invalid permutation description used at: GRelation::permute");
    
    return permute(desc.getPerm());
  }
   
  GRelation GRelation::shiftRight(int n) const {
    return
      GRelation(
		Impl(new RelationImpl(pimpl_->shiftRight(n)))
		);
  }

  /*
   * Cross product
   */ 
  GRelation GRelation::timesULeft(int n) const {
    return
      GRelation(Impl(new RelationImpl(pimpl_->timesULeft(n))));
  }


  GRelation GRelation::timesURight(int n) const {
    return
      GRelation(Impl(new RelationImpl(pimpl_->timesURight(n))));
  }
  
  GRelation GRelation::times(const GRelation& r) const {
    return join(0,r);
  }
  
  /*
   * Relational algebra
   */ 
  GRelation GRelation::join(int j,const GRelation& r) const {
    typedef boost::error_info<struct tag_invalid_join,std::string>
      invalid_join;

    if (arity() < j || r.arity() < j)
      throw InvalidJoin()
		  << errno_code(errno)
		  << invalid_join("There are not enough columns for the join");

    return
      GRelation(
		Impl(new RelationImpl(pimpl_->join(j, *(r.pimpl_))))
		);
  }

  GRelation GRelation::follow(int f,const GRelation& right) const {
    /// \todo handle arity errors with exceptions

    //  if (arity() < j || r.arity() < j)
    //    throw InvalidJoin()
    //      << errno_code(errno)
    //      << invalid_join("There are not enough columns for the join");

    return
      GRelation(
		Impl(new RelationImpl(pimpl_->follow(f, *(right.pimpl_))))
		);
  }

  GRelation GRelation::project(int p) const {
    typedef boost::error_info<struct tag_projection,std::string>
      projection;

    if(p <= 0 || p > arity()) {
      throw InvalidProjection()
        << errno_code(errno)
        << projection("Invalid columns to project on");
    }
    return
      GRelation(
		Impl(new RelationImpl(pimpl_->project(p)))
		);
  }

  /*
   * Quantification
   */ 
  GRelation GRelation::exists(int c) const {
    return
      GRelation(
		Impl(new RelationImpl(pimpl_->exists(c)))
		);
  }

  GRelation GRelation::unique(int c) const {
    return
      GRelation(
		Impl(new RelationImpl(pimpl_->unique(c)))
		);
  }

  GRelation GRelation::unique(const std::vector<int>& c) const {
    return
      GRelation(
		Impl(new RelationImpl(pimpl_->unique(c)))
		);
  }

  GRelation GRelation::forall(int c) const {
    return
      GRelation(
		Impl(new RelationImpl(pimpl_->forall(c)))
		);
  }


  /*
   * Test operations
   */ 
  bool GRelation::subsetEq(const GRelation& r) const {
    return VarImpl::subsetEq(*pimpl_,*r.pimpl_);
  }

  bool GRelation::superset(const GRelation& r) const {
    return VarImpl::superset(*pimpl_,*r.pimpl_);
  }

  bool GRelation::disjoint(const GRelation& r) const {
    return VarImpl::disjoint(*pimpl_,*r.pimpl_);
  }

  bool GRelation::eq(const GRelation& r) const {
    return *pimpl_ == *(r.pimpl_);
  }

  bool GRelation::empty(void) const {
    return pimpl_->empty();
  }

  bool GRelation::universe(void) const {
    return pimpl_->universe();
  }

  /*
   * Relation information
   */ 
  int GRelation::arity(void) const {
    return pimpl_->arity();
  }

  double GRelation::cardinality(void) const {
    return pimpl_->cardinality();
  }

  /*
   * Content access
   */ 
  Tuple GRelation::pickOneTuple(void) const {
    /// \todo throw an exception
    assert(!empty() && "Relation is empty, nothing to return");
    return
      pimpl_->pickOneTuple();
  }

  /*
   * Relation output
   */ 
  void GRelation::print(std::ostream& os) const {
    pimpl_->print(os);
  }

  std::ostream& operator<< (std::ostream& os, const GRelation& r) {
    r.print(os);
    return os;
  }


Le 25 nov. 2011 à 18:25, Frank Goenninger a écrit :

> Am 25.11.2011 um 17:08 schrieb Sascha Van Cauwelaert:
> 
>> I tried what you did and it works. The problem is that the project I try to interface is much more complicated than this (and I cannot modify it) but still it helps.
>> 
>> I will try to do the same thing with the real class GRelation. But for this, I need to use another C compiler than the standard one (I have to use the last version of gcc) and to modify the passed options (not only add some). 
> 
> Ok. This all leads to the question: What is the class GRelation really looking like? What is it that makes is so complicated? What is the "project" you are referring to?  I jfgi and found those entries for GRelation:
> 
> http://waffles.sourceforge.net/
> 
> http://www.ibm.com/developerworks/linux/tutorials/l-glib/section9.html
> 
> http://www.google.de/url?sa=t&rct=j&q=grelation&source=web&cd=6&ved=0CD4QFjAF&url=http%3A%2F%2Fwww-hera-b.desy.de%2Fsubgroup%2Fsoftware%2Fclue%2FBEE-0-98%2Fgrelation%2Fmanual.ps.gz&ei=fs7PTs6EMNCEhQex6NTmDQ&usg=AFQjCNGTikFM_ttnj1PqfaEQHm9H0Ey_Ow&sig2=q_nFQ9Jxnc5OB8A_b0sjMw
> 
> Something else?
> 
>  Frank

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/cffi-devel/attachments/20111126/029c722f/attachment.html>


More information about the cffi-devel mailing list