私の謙虚な意見では、IoCテクノロジーは多かれ少なかれ重要なプロジェクトの不可欠なコンポーネントであるため、IoCコンテナーを適切に使用することが重要です。 そのため、PocoCapsuleとの出会いの後、この記事を書くことにしました。 私の経験を共有するためだけでなく、私がすべてを正しく行い、すべてを正しく理解したことを確認するためにも、あなたが知っているように、何かを理解する最良の方法はそれを他の人に説明することです。
PocoCapsuleを使用して「Hello world」アプリケーションを起動するのに約6時間かかりました。 さらに、時々私はすべてを地獄に送りたいと思った。 テキスト「failure:null」が表示されたときに手が落ちますが、教科書に従ってすべてを行います。 Spring IoCでの同様の開始には約30〜60分かかりますが、
PocoCapsuleは、標準C ++オブジェクト(POCO)で動作するIoCコンテナーであり、非常に複雑です。 xml構成ファイルを読み取った後、PocoCapsuleは必要なPOCOオブジェクトを直接作成できません。 C ++では、リフレクションメカニズムはありません。
たとえば、クラスFooがあります。
class Foo {
public :
Foo() {};
~Foo() {};
}
* This source code was highlighted with Source Code Highlighter .
およびxmlコンテナー構成:
<poco-application-context>
<bean class = "Foo"
destroy-method= "delete"
lazy-init= "false" >
</bean>
</poco-application-context>
* This source code was highlighted with Source Code Highlighter .
xml構成を読み取った後、PocoCapsuleはクラスFooのオブジェクトを作成する必要があります。 しかし、それを行う方法は? 結局のところ、PocoCapsuleはソースコードに依存せず、このFooがどのようなクラスで、どのように処理するかを知ることができないため、当然、このクラスのオブジェクトを直接作成することはできません。
この問題を解決するために、PocoCapsuleはクラスごとにプロキシメソッドを生成します-クラスを直接処理するメソッド(作成、削除など)。 したがって、Fooコンストラクターを呼び出すには、メソッドが生成されます。
// ---------------------------------------
// Proxies of constructors and factories
// ---------------------------------------
//
// new Foo()
//
static void * _poco_proxy_0( void * _poco_this, void * _poco_params[])
{
Foo* _poco_var_retv;
_poco_var_retv = new Foo();
return ( void *)_poco_var_retv;
}
* This source code was highlighted with Source Code Highlighter .
それに応じて削除するには:
// -------------------------------------
// Proxies of dup and destroy methods
// -------------------------------------
//
// delete(Foo*)
//
static void * _poco_proxy_1( void * _poco_this, void * _poco_params[])
{
int _poco_i = 0;
Foo* _poco_var_0 = (Foo*)(_poco_params[_poco_i++]);
delete(
_poco_var_0);
return ( void *)0UL;
}
* This source code was highlighted with Source Code Highlighter .
次に、これらの「poco_proxy」をコンテナに登録するためのメソッドも生成されます。 最終的に、これらのプロキシメソッドは、プロジェクトに接続し、クラスとPocoCapsuleの間のリンクである共通のソースファイルに結合されます。
元の「Hello word」の問題。 (Ubuntu 10.04 LTS環境)
PocoCapsuleに出会ったときに遭遇した問題を順番に説明します。
- バイナリを解凍した後、プロキシジェネレーターは起動しません(bin / pxgenproxy)。 次のものがあります。
caiiiycuk @ caiiiycuk-laptop:〜/ pococapsule-cpp / bin $ ./pxgenproxy ./pxgenproxy:未定義のシンボル:JNI_CreateJavaVM
同時に、JREとJDKの両方をインストールしています(pocoapsuleはJavaを使用してプロキシを生成するだけでなく、プロキシも生成します)。
この問題を解決するには、環境変数POCOCAPSULE_DIR =(展開されたPocoCapsuleのあるフォルダー)を設定する必要があります。 この要件がドキュメントのどこにも記載されていないのは非常に古いことです。 箱から出してすぐに動作するはずですが、私には動作しませんでした。
正しいアルゴリズムは次のとおりです。
caiiiycuk@caiiiycuk-laptop:~/pococapsule-cpp/bin$ export POCOCAPSULE_DIR=/home/caiiiycuk/pococapsule-cpp/
caiiiycuk@caiiiycuk-laptop:~/pococapsule-cpp/bin$ ./pxgenproxy
------------------------------------------------------------
Pocomatic Software, Dynamic Proxy Generator, version 1.0
------------------------------------------------------------
Usage:
./pxgenproxy (xml-file|option)*
options:
-help : print this page
-s=[name] : suffix and extend name of proxy file,
default value is '_reflx.cc'
-H=[std-header-file] : use the specified standard header file
-h=[usr-header-file] : use the specified user defined header file
-r=[gather|scatte] : recursively step into imported resources and gather or scatte
proxy generation result into one or multiple individual proxy file(s)
caiiiycuk@caiiiycuk-laptop:~/pococapsule-cpp/bin$
* This source code was highlighted with Source Code Highlighter .
- コンテキストを上げようとしても、何も起こりません-コンテキストの代わりに陽気なnullを取得します。 チュートリアルに従ってすべてを実行し、コンパイルされたmain.Cを実行すると、cxtx == nullなので「failure:null」が得られます。
/****************************************************************************/
/* */
/* Copyright 2006, by Pocomatic Software, LLC. All Rights Reserved. */
/* */
/****************************************************************************/
#include "pocoapp.h"
#include <stdio.h>
#include < string .h>
int main( int argc, char ** argv)
{
POCO_AppEnv* env = POCO_AppContext::initDefaultAppEnv(argc, argv);
POCO_AppContext* ctxt = POCO_AppContext::create( "setup.xml" , "file" );
if ( ctxt == NULL || !ctxt->initSingletons() ) {
printf( "failure: %s\n" , env->get_message());
return -1;
}
ctxt->terminate();
ctxt->destroy();
return 0;
}
* This source code was highlighted with Source Code Highlighter .
理由は同じ「POCOCAPSULE_DIR」です:開始する前にこの環境変数を宣言すると、すべてが動作し始めます。 これは、PocoCapsuleがデフォルトでJAXPを使用してxmlファイルを解析するためです。 悲しいけれど本当です:(ご存じのとおり、xmlファイルの解析にjavaを使用するのはあまりいいことではありません...幸いなことに、それを取り除くには2つの方法があります。私は最初の方法で行ったが、問題が追加されただけでした。
- Xerces-C ++バージョン2.7用にコンパイルされたPocoCapsuleネイティブxml-reader(libpocoxml.so)は、すでに時代遅れになっており、他のどこからもアクセスできません。 この問題を解決するには、pococapsuleのソースをダウンロードし、xerces-c(dev)をシステムにインストールし、pococapsule-cpp-1.1-src / src / xmlreaderフォルダーに移動してmakeを実行します。 コンパイルが成功したら、適切なlibpocoxml.soをlib dadから取得します。
- PocoCapsuleは、Xerces-C ++(libpocoxml.so)を使用するという私たちの願望を無視し、JAXP(libpocoxsl.so)を必要とします。 チュートリアルでは、libpocoxml.soをプロジェクトに接続すると、PocoCapsuleはlibpocoxsl.soの代わりにそれを自動的に使用することを示しています。 はい、そうです-私の「Hello word」プロジェクトで機能しました。 しかし、他のライブラリも接続されている別の(より複雑な)プロジェクトでは、libpocoxml.soを接続しても効果はありません。プロジェクトには頑固にlibpocoxsl.soが必要です。 タンバリンとのダンスに失敗した後、私は愚かにlibpocoxml.soの名前をlibpocoxsl.soに変更しましたが、すべてうまくいきました。
とりわけ、教科書の「Hello World」プロジェクトには動的リンクが含まれます。 私はそれが何かをデートする必要のためにはるかに簡単にできると信じています。
最も単純な「Hello World」
開発には、Ubuntu 10.04 LTSとNetbeans 6.8 、およびPocoCapsule 1.0バイナリを使用します。
- 新しいC ++プロジェクトを作成します。 ヘッダーファイルをインクルードします(プロジェクトプロパティ->ビルド-> C ++コンパイラ->インクルードディレクトリ:pococapsule_dir / include)。 libpococapsule.soを探す場所をリンカーに指示します(プロジェクトプロパティ->ビルド->リンカー->ライブラリ:pococapsule_dir / lib / libpococapsule.so)。
- クラスFoo(Foo.h)を作成します。
#ifndef _FOO_H
#define _FOO_H
#include <iostream>
class Foo {
public :
Foo() {
std::cout << "Hello world!" << std::endl;
}
};
#endif /* _FOO_H */
* This source code was highlighted with Source Code Highlighter .
- xmlコンテキスト(context.xml)を作成します。
<?xml version= "1.0" encoding= "iso-8859-1" ?>
<!DOCTYPE poco-application-context
SYSTEM "http://www.pocomatic.com/poco-application-context.dtd" >
<poco-application-context>
<bean class = "Foo"
destroy-method= "delete"
lazy-init= "false" >
</bean>
</poco-application-context>
* This source code was highlighted with Source Code Highlighter .
- Fooクラスのプロキシメソッドを生成します。 プロジェクトディレクトリでコンソールを開き、次を実行します。
export POCOCAPSULE_DIR=( PocoCapsule)
$POCOCAPSULE_DIR/bin/pxgenproxy -h=Foo.h context.xml
* This source code was highlighted with Source Code Highlighter .
生成に成功すると、context_reflx.ccファイルが表示されます。このファイルをプロジェクトに追加して、NetBeansがビルドするようにします(ソースファイル->既存のアイテムの追加)。 すべてが正常にビルドされることを確認します。
- XMLコンテキストをエンコードして、JAXPを取り除きます。 プロジェクトディレクトリでコンソールを開き、次を実行します。
export POCOCAPSULE_DIR=( PocoCapsule)
$POCOCAPSULE_DIR/bin/pxencode context.xml
* This source code was highlighted with Source Code Highlighter .
出力はcontext_poco.ctxを取得します。
- main.cppを編集します。
#include "pocoapp.h"
#include <stdio.h>
#include < string .h>
int main( int argc, char ** argv)
{
POCO_AppEnv* env = POCO_AppContext::initDefaultAppEnv(argc, argv);
POCO_AppContext* ctxt = POCO_AppContext::create( "context_poco.ctx" , "file" );
if ( ctxt == NULL || !ctxt->initSingletons() ) {
printf( "failure: %s\n" , env->get_message());
return -1;
}
ctxt->terminate();
ctxt->destroy();
return 0;
}
* This source code was highlighted with Source Code Highlighter .
実行すると、「Hello World!」が表示されます。
それだけです:)
ご清聴ありがとうございました。