Libzypp/Design/Binary

Şuraya atla: kullan, ara

Program Kitaplığında İkili Bağdaşıklık

Sabit ve serbest Kitaplıklar için ,Kod'un büyük ve önemli gözden geçirmeleri sırasında ikili bağdaşırlığı korumak çok önemli. Kitaplık geliştiricileri ürünün kitaplığında çok sık ikili bağdaşımsız değişim yaparak kullanıcıları yapancılaştırmamalı.

Bir kitaplık genellikle bir çok sayıda ki arabirimi dışarıya taşır.Bunlar yordam isimlerini içerirler, bu yordamların sinyalleri ya da benzerleri , evrensel değişkenler, yapılar, yapı alanları (hem tür hem de anlam açısından),sayı değerleri açısından anlamı ve kitaplık tarafından yapılmış olan anlambilim alanı. İkili bağdaşırlığı birarada tutmak demek bu arabirimlerin değiştirlmeyeceği demektir. İkili bağdaşırlığı bozmadan yeni arabirimler ekleyebilirsiniz, fakat eski programlar artık doğru çalışmadığı için varolanları değiştiremezsiniz.

Bu bölüm kitaplık kodunuzun eski uyarlamasını kullanarak ikili bağdaşıklığı nasıl yapacağınız konusunda bir dizi ipucunu içeriyor.

İkili bağdaşıklığı korumak, Kod'un önceki versiyonlarına karşı derlenmiş olan program ve konu dosyalarının kitaplığın yer değiştirmesi durumunda yeniden derlenmesine gerek kalmaksızın çalışmaya devam etmesi anlamına geliyor.

İkili Bağdaşıklık için iyi bir açıklama KDE projesinde bulunabilir:

http://developer.kde.org/documentation/other/binarycompatibility.html

İkili Bağdaşıklığı korumanın temel stratejisi data üyelerinin ve sanal işlemlerin kendi sınıflarındaki <classname>Impl olarak adlandırılan data üyelerini ve sanal işlevlerini elde tutmaktır.

Bu veri üyelerine ve sanal işlemlere,<classname> sınıfı olarak tanımlanan işaretçi yoluyla ulaşılabilir.

Mekanizmayi gösteren Dependencies ( Bağımlılık ) sınıfından basit bir örnek:

/*---------------------------------------------------------------------\
|                          ____ _   __ __ ___                          |
|                         |__  / \ / / . \ . \                         |
|                           / / \ V /|  _/  _/                         |
|                          / /__ | | | | | |                           |
|                         /_____||_| |_| |_|                           |
|                                                                      |
\---------------------------------------------------------------------*/
/** \file	zypp/Dependencies.h
*
*/
#ifndef ZYPP_DEPENDENCIES_H
#define ZYPP_DEPENDENCIES_H

#include <iosfwd>

#include "zypp/base/PtrTypes.h"

#include "zypp/CapSetFwd.h"

///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
namespace detail
{ /////////////////////////////////////////////////////////////////
DEFINE_PTR_TYPE(DependenciesImpl)
/////////////////////////////////////////////////////////////////
} // namespace detail
///////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////
//
//	CLASS NAME : Dependencies
//
/** */
class Dependencies
{
public:
/** Default ctor */
Dependencies();
/** Factory ctor */
explicit
Dependencies( detail::DependenciesImpl_Ptr impl_r );
/** Dtor */
~Dependencies();

public:
/**  */
const CapSet & provides() const;
/**  */
const CapSet & prerequires() const;
/**  */
const CapSet & requires() const;
/**  */
const CapSet & conflicts() const;
/**  */
const CapSet & obsoletes() const;
/**  */
const CapSet & recommends() const;
/**  */
const CapSet & suggests() const;
/**  */
const CapSet & freshens() const;

/**  */
void setProvides( const CapSet & val_r );
/**  */
void setPrerequires( const CapSet & val_r );
/**  */
void setRequires( const CapSet & val_r );
/**  */
void setConflicts( const CapSet & val_r );
/**  */
void setObsoletes( const CapSet & val_r );
/**  */
void setRecommends( const CapSet & val_r );
/**  */
void setSuggests( const CapSet & val_r );
/**  */
void setFreshens( const CapSet & val_r );

private:
/** Pointer to implementation */
detail::DependenciesImpl_Ptr _pimpl;
public:
/** Avoid a bunch of friend decl. */
detail::DependenciesImpl_constPtr sayFriend() const;
};
///////////////////////////////////////////////////////////////////

/** \relates Dependencies Stream output */
extern std::ostream & operator<<( std::ostream & str, const Dependencies & obj );

/////////////////////////////////////////////////////////////////
} // namespace zypp
///////////////////////////////////////////////////////////////////
#endif // ZYPP_DEPENDENCIES_H

Dependencies sınıfının _pimpl olarak adlandırılan DependenciesImpl sınıfı işeretçisi olduğunu görürüz. called . Bu işaretçi ile Dependencies sınıfı DependenciesImpl ın üye değişkenlerine erişebilir.Böylece yapılan her güncelleme gelecek için İkili bağdaşık olacaktır :

/*---------------------------------------------------------------------\
|                          ____ _   __ __ ___                          |
|                         |__  / \ / / . \ . \                         |
|                           / / \ V /|  _/  _/                         |
|                          / /__ | | | | | |                           |
|                         /_____||_| |_| |_|                           |
|                                                                      |
\---------------------------------------------------------------------*/
/** \file	zypp/Dependencies.cc
*
*/
#include <iostream>

#include "zypp/base/ReferenceCounted.h"
#include "zypp/base/NonCopyable.h"
#include "zypp/Dependencies.h"
#include "zypp/CapSet.h"

using namespace std;

///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////
namespace detail
{ /////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////
//
//	CLASS NAME : DependenciesImpl
//
/** Dependencies implementation */
struct DependenciesImpl : public base::ReferenceCounted, private base::NonCopyable
{
/**  */
CapSet _provides;
/**  */
CapSet _prerequires;
/**  */
CapSet _requires;
/**  */
CapSet _conflicts;
/**  */
CapSet _obsoletes;
/**  */
CapSet _recommends;
/**  */
CapSet _suggests;
/**  */
CapSet _freshens;

static DependenciesImpl_Ptr nodeps()
{
if ( !_nodeps ) { _nodeps = new DependenciesImpl; _nodeps->ref(); }
return _nodeps;
}

private:
static DependenciesImpl_Ptr _nodeps;
};
///////////////////////////////////////////////////////////////////
IMPL_PTR_TYPE(DependenciesImpl)
DependenciesImpl_Ptr DependenciesImpl::_nodeps;
///////////////////////////////////////////////////////////////////

/** \relates DependenciesImpl Stream output */
inline std::ostream & operator<<( std::ostream & str, const DependenciesImpl & obj )
{
str << "PROVIDES:" << endl << obj._provides;
str << "PREREQUIRES:" << endl << obj._prerequires;
str << "REQUIRES:" << endl << obj._requires;
str << "CONFLICTS:" << endl << obj._conflicts;
str << "OBSOLETES:" << endl << obj._obsoletes;
str << "RECOMMENDS:" << endl << obj._recommends;
str << "SUGGESTS:" << endl << obj._suggests;
str << "FRESHENS:" << endl << obj._freshens;
return str;
}

/////////////////////////////////////////////////////////////////
} // namespace detail
///////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////
//
//	CLASS NAME : Dependencies
//
///////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////
//
//	METHOD NAME : Dependencies::Dependencies
//	METHOD TYPE : Ctor
//
Dependencies::Dependencies()
: _pimpl( detail::DependenciesImpl::nodeps() )
{}

///////////////////////////////////////////////////////////////////
//
//	METHOD NAME : Dependencies::Dependencies
//	METHOD TYPE : Ctor
//
Dependencies::Dependencies( detail::DependenciesImpl_Ptr impl_r )
: _pimpl( impl_r ? impl_r : detail::DependenciesImpl::nodeps() )
{}

///////////////////////////////////////////////////////////////////
//
//	METHOD NAME : Dependencies::~Dependencies
//	METHOD TYPE : Dtor
//
Dependencies::~Dependencies()
{}

///////////////////////////////////////////////////////////////////
//
//	METHOD NAME : Dependencies::sayFriend
//	METHOD TYPE : detail::DependenciesImplconstPtr
//
detail::DependenciesImpl_constPtr Dependencies::sayFriend() const
{ return _pimpl; }

const CapSet & Dependencies::provides() const
{ return _pimpl->_provides; }

const CapSet & Dependencies::prerequires() const
{ return _pimpl->_prerequires; }

const CapSet & Dependencies::requires() const
{ return _pimpl->_requires; }

const CapSet & Dependencies::conflicts() const
{ return _pimpl->_conflicts; }

const CapSet & Dependencies::obsoletes() const
{ return _pimpl->_obsoletes; }

const CapSet & Dependencies::recommends() const
{ return _pimpl->_recommends; }

const CapSet & Dependencies::suggests() const
{ return _pimpl->_suggests; }

const CapSet & Dependencies::freshens() const
{ return _pimpl->_freshens; }

void Dependencies::setProvides( const CapSet & val_r )
{ _pimpl->_provides = val_r; }

void Dependencies::setPrerequires( const CapSet & val_r )
{ _pimpl->_prerequires = val_r; }

void Dependencies::setRequires( const CapSet & val_r )
{ _pimpl->_requires = val_r; }

void Dependencies::setConflicts( const CapSet & val_r )
{ _pimpl->_conflicts = val_r; }

void Dependencies::setObsoletes( const CapSet & val_r )
{ _pimpl->_obsoletes = val_r; }

void Dependencies::setRecommends( const CapSet & val_r )
{ _pimpl->_recommends = val_r; }

void Dependencies::setSuggests( const CapSet & val_r )
{ _pimpl->_suggests = val_r; }

void Dependencies::setFreshens( const CapSet & val_r )
{ _pimpl->_freshens = val_r; }

/******************************************************************
**
**	FUNCTION NAME : operator<<
**	FUNCTION TYPE : std::ostream &
*/
std::ostream & operator<<( std::ostream & str, const Dependencies & obj )
{
return str << *obj.sayFriend();
}

/////////////////////////////////////////////////////////////////
} // namespace zypp
///////////////////////////////////////////////////////////////////

Bu strateji virtual functions (sanal işlemler) için de kullanılmalı.

Resolvable sınıfı ve ondan türeyen tüm diğer sınıfların tanımı biraz daha karmaşık. Ancak konsept aynı. Tam tanıma buradan erişilebilir.:Binary Compatibility

Resolvable sınıf ile "normal" sınıf arasındaki temel farklılık anlık yaratılar olur. Bu, bu bölümde tanımlanan mekanizmanın kendisi tarafından yapılmalıdır:FAQ


Trac'ta 'schubi' tarafından yapılan son düzeltme '12/06/05 12:09:08'


Trac'ta 'schubi' tarafından yapılan son düzeltme '12/06/05 12:09:08'


Trac'ta 'schubi' tarafından yapılan son düzeltme '12/06/05 12:09:08'


Trac'ta 'schubi' tarafından yapılan son düzeltme '12/06/05 12:09:08'


Trac'ta 'schubi' tarafından yapılan son düzeltme '12/06/05 12:09:08'