braintag

公開してしまう備忘録

ミラーリングポートハブが無いが、全パケットをキャプチャしたい場合、NIC2枚使ってブリッジ設定

ミラーリングポートハブは買うと高い。
リピータハブは10MB程度なので遅すぎてイヤだ。

そこら辺のPCに余ったNIC(LANカード)をさしてNIC2枚状態にし、
そのPCを間に挟めば、全パケットをキャプチャ出来るのでは?

と思ってやってみたら拍子抜けするくらい簡単だったので、手順を以下に示します。

1.WindowsXPがインストールされたPCを用意します


2.そのPCにNICを刺してドライバ入れて、LANデバイスが2つある状態にします


3.パケットキャプチャしたい経路に、そのPCを挟みます


4.ネットワーク接続のプロパティを開きます


5.2つのデバイスを選択して右クリックして"ブリッジへ追加"を選択


6.Wireshak等でどちらかのデバイスをキャプチャ

以上です。

CDHtmlDialogから、javascript関数の呼び出し方法

[初回]MFCアプリケーションのユーザインタフェースをすべてJavascript(JQuery)におまかせしてしまう - braintag
[前回]CDHtmlDialogにて、html間の値の受け渡し方法 - braintag

これらの続きです。

呼び出すjavascriptの関数は以下のコード

<script type="text/javascript">
    function calljsfuncfromcpp() {
        alert("calljsfunc");
    }
</script>

execScriptを使う方法

CDHtmlDialogのメンバで以下のコードを実行

     CComPtr<IHTMLWindow2> HTML2Wind;
    m_spHtmlDoc->get_parentWindow(&HTML2Wind);

    BSTR langstr = ::SysAllocString(L"javascript");
    BSTR funcname = ::SysAllocString(L"calljsfuncfromcpp()");
    VARIANT vempty = {0};
    HTML2Wind->execScript(funcname, langstr, &vempty);
    SysFreeString(langstr);
    SysFreeString(funcname);

ただ、この方法は、戻り値がわかりません。
(vemptyに戻り値は入らない)

http://d.hatena.ne.jp/kinokorori/20090719
ここの手法が一番いいようです。

逆の方法、javascriptからC++のfunctionを呼び出す方法

ググるといろいろ方法はありそうで、以下をやってみましたがダメでした。

・DECLARE_DISPATCH_MAP,window.externalを使う方法(ActiveXの警告がどうしても消えない)
・IDispatchを継承して使う方法(トライしてみましたが、難しすぎて成功しませんでした)

仕方ないので、以下の方法でjavascriptからC++側のfunctionを呼びました。
html+javascript側の記述

function callcppfunc()
{
   $("callcppfunc").val("data");
   $("callcppfunc").trigger("click");
}
<input type="hidden" id="callcppfunc" onclick="callcppfunc()">

MFC側の方法
CDHtmlDialogのDHTML_EVENT_ONCLICKでイベントを受け取り、DDX_DHtml_ElementValueでデータ取得

以上の方法でお茶を濁しました。
当然、戻り値は返せませんので、工夫が必要です。

CDHtmlDialogにて、html間の値の受け渡し方法

MFCアプリケーションのユーザインタフェースをすべてJavascript(JQuery)におまかせしてしまう - braintag

これの続きですが、今回はJavascriptは関係ありません。

今回は、MFC<->html間の、値の受け渡し方法をやります。

htmlの編集

前回使用したプロジェクトの"testJQuery.htm"の最後に、入力欄を用意します。
あとで、ここで指定した"id"を、MFCのヘルパーマクロに登録します。

<input id="testJQueryValue" />
<BR>
</BODY>
</HTML>

変数の追加

"testJQueryDlg.h"に、取得用のCStringを用意します。

//html value
	CString testjquery_value_;

};

DDX_DHtmlヘルパーマクロの登録

"testJQueryDlg.cpp"の、DoDataExchangeに、ヘルパーマクロを追加します。
2つ目の引数は、"testJQuery.htm"に記述されている、値を取得したい"id"です。

void CtestJQueryDlg::DoDataExchange(CDataExchange* pDX)
{
	CDHtmlDialog::DoDataExchange(pDX);
	DDX_DHtml_ElementValue(pDX, _T("testJQueryValue"), testjquery_value_);
}

値のセット

ヘルパーマクロに登録した後は、通常のMFCアプリと同じです。UpdateData(FALSE)で値を設定できます。
ここでは、OnInitDialogで、値をセットしてみます。

	//設定値のセット
	testjquery_value_ = _T("testjqueryvalue");;
	UpdateData(FALSE);

値の取得

MFCと同じように、UpdateData(TRUE)で値が取れます。
ここでは、OKボタンを押すと、メッセージボックスで表示されるようにしました。

HRESULT CtestJQueryDlg::OnButtonOK(IHTMLElement* /*pElement*/)
{
	UpdateData(TRUE);
	AfxMessageBox(testjquery_value_);
	OnOK();
	return S_OK;
}


以上で、値のやり取りは終わりです。
次こそはイベントのやり取りを行います。

[前回]MFCアプリケーションのユーザインタフェースをすべてJavascript(JQuery)におまかせしてしまう - braintag
[次回]CDHtmlDialogから、javascript関数の呼び出し方法 - braintag

MFCアプリケーションのユーザインタフェースをすべてJavascript(JQuery)におまかせしてしまう

wpfがある.NETと違って、MFCアプリを作っていると、ユーザインタフェースの見た目がしょぼくなりがち。
ちょっと凝ったことをしようとすると、すぐに複雑化してしまう。

面倒なので、ユーザインタフェースをJavascriptにおまかせしてしまう方法。
(CDHtmlDialogを使うので、MFC限定です)

今回は、Javascriptを使うところまでを記述します。
JavascriptとMFC間のイベントの受け渡しは次回やります。

1.プロジェクトの作成

VisualStudioから、"testJQuery"という名前で、MFCのプロジェクトを作成します。
CDHtmlDialogを使用するため、以下をチェックしてください

2.Javascriptをリソースへ追加する

Javascriptのライブラリとして、JQueryを使います。
jQuery

"jquery.js"を、作成したプロジェクトの"res"フォルダにコピーしておきます。

VisualStudioのソリューションエクスプローラーの、リソースフォルダで右クリックをして、"追加"、"既存の項目"で、先程コピーした"res\jquery.js"を選択します。

VisualStudioのソリューションエクスプローラーの、リソースビューを開き、プロジェクトのトップで右クリックをして、"リソース"の追加、"カスタム"を選択し、"JS"を入力します。

こんな感じになります。

VisualStudioのソリューションエクスプローラーの"testJQuery.rc"を右クリック、"コードの表示"を選択します。

"JS"の項目が空の状態になっているので、ここに、"jquery.js"を追加します。

/////////////////////////////////////////////////////////////////////////////
//
// JS
//
IDR_JS1 JS "res\\jquery.js"

3.JQueryの実行

"testJQuery.htm"を開いて、以下のように書き換えます。*1

<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=shift_jis"/>
<SCRIPT src="res:/JS/#129" type=text/javascript>
</SCRIPT>
<script type="text/javascript">
    function fadeIn() {
        $("#contents").fadeIn("fast");
    }
    function fadeOut() {
        $("#contents").fadeOut();
    }
</script>
</HEAD>
<BODY ID=CtestJQueryDlg BGCOLOR=LIGHTGREY style="font-family:MS UI Gothic;font-size:9">

<TABLE WIDTH=100% HEIGHT=100%>
<TR WIDTH=100% HEIGHT=45%>
<TD ALIGN=CENTER VALIGN=BOTTOM id="contents">
TODO: Place controls here.
</TD>
</TR>
<TR WIDTH=100% HEIGHT=100%>
<TD ALIGN=RIGHT VALIGN=BOTTOM>
<BUTTON STYLE="WIDTH:100" ID="ButtonFadeIn" onClick="fadeIn()">fadeIn</BUTTON>
<BUTTON STYLE="WIDTH:100" ID="ButtonFadeOut" onClick="fadeOut()">fadeOut</BUTTON>
<BUTTON STYLE="WIDTH:100" ID="ButtonOK"">OK</BUTTON>&nbsp;<BUTTON STYLE="WIDTH:100" ID="ButtonCancel">キャンセル</BUTTON>
</TD>
</TR>
</TABLE>

</BODY>
</HTML>

ビルドして、実行します。

出来上がりました。
"fadeIn"ボタンを押すと、中央の文字列がフェードイン、"fadeOut"を押すと、フェードアウトします。

今回はここまでです。
次回はイベントの受け渡しを行います。

[次回]CDHtmlDialogにて、html間の値の受け渡し方法 - braintag
[次々回]CDHtmlDialogから、javascript関数の呼び出し方法 - braintag

*1:res:/JS/#129の、#129は、"resource.h"のリソース番号です。

VisualStudio(VC9) でlog4cxxをつかう その3 VisualStudioのデバッグ出力へ

VisualStudio(VC9) でlog4cxxをつかう - braintag
VisualStudio(VC9) でlog4cxxをつかう その2 - braintag
これらの続きです。

今回は、log4cxxの出力を、VisualStudioデバッグ出力にも出したいと思います。
"log4j.properties"でどうにかする方法は見つからなかったため、非常にめんどくさいです。

前回のソースから、以下のように修正します。

// logtest.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"

#include <log4cxx/logger.h>


//<--ここから追加
#include <log4cxx/propertyconfigurator.h>
#include <log4cxx/patternlayout.h>
#include <log4cxx/helpers/transcoder.h>
#include <log4cxx/nt/outputdebugstringappender.h>
//-->ここまで

using namespace log4cxx;

int _tmain(int argc, _TCHAR* argv[])
{
	LoggerPtr logger(Logger::getLogger("logtest"));

//<--ここから追加
	//ファイル指定読み込みしないと、既存のlogger動作が無視されたので追加
	log4cxx::PropertyConfigurator::configure("./log4j.properties");
	//パターンレイアウトの作成
	log4cxx::LogString logstr;
	log4cxx::helpers::Transcoder::decode("%d %5p %l %c{1} - %m%n",logstr);//パターンレイアウト
	log4cxx::PatternLayoutPtr layoutPtr = new log4cxx::PatternLayout(logstr);

	//OutputDebugStringのappenderを作成
	log4cxx::nt::OutputDebugStringAppender* pODSA = new log4cxx::nt::OutputDebugStringAppender();

	//OutputDebugStringのappenderにパターンレイアウトのセット
	pODSA->setLayout(layoutPtr);
	logger->addAppender(pODSA);//OutputDebugStringのappenderを追加
//-->ここまで

	LOG4CXX_INFO(logger,"info")
	LOG4CXX_FATAL(logger,"fatal");
	LOG4CXX_ERROR(logger,"error");
	LOG4CXX_WARN(logger,"warn");
	LOG4CXX_DEBUG(logger,"debug");


  return 0;
}

ビルド後、実行すると、VisualStudioデバッグ出力に、以下のように出力されるようになりました。

ただし、"OutputDebugString"を使用しているので、リリースビルドでも出力されちゃいます。
リリースビルドで出力させたくない場合は、_DEBUGマクロでなんとかしてください。

VisualStudio(VC9) でlog4cxxをつかう その2

VisualStudio(VC9) でlog4cxxをつかう - braintag

の続き

付属のユニットテストを実行してみる

"プロジェクトの追加"で、以下のプロジェクトを追加

C:\lib\log4cxx\apache-log4cxx-0.10.0\projects\testsuite.dsw

プロジェクトの依存にて、apr,apriconv,aprutil,log4cxx,xmlをチェック

構成プロパティの作業ディレクトリを以下に指定

../src/test/resources

実行してみる(注意:ユニットテスト実行時にも、SEDがインストールされている環境が必要)

あれ、あまり成功してないや・・・。

なぜなんだろう。


気にせず次に行きます。良くないんだろうけど。

プロジェクト"logtest"を追加して、以下のソースにします。

#include "stdafx.h"

#include <log4cxx/logger.h>

using namespace log4cxx;

int _tmain(int argc, _TCHAR* argv[])
{
	LoggerPtr logger(Logger::getLogger(""));
	LOG4CXX_INFO(logger,"info")
	LOG4CXX_FATAL(logger,"fatal");
	LOG4CXX_ERROR(logger,"error");
	LOG4CXX_WARN(logger,"warn");
	LOG4CXX_DEBUG(logger,"debug");
        //"LOG4CXX_*"のマクロを使うとファイル名、
        //行番号を出力できるので、こちらがお勧め

  return 0;
}

プロジェクトの依存関係を指定します。

カレントディレクトリ(C:\lib\log4cxx\apache-log4cxx-0.10.0\logtest)に、"log4j.properties"
ファイルを置きます。
行番号の"%l"を追加しています。log4jと違って、遅くならないらしいので。

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %5p %l %c{1} - %m%n

log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=logtest.log
log4j.appender.file.Apppend=true
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d %5p %l %c{1} - %m%n

log4j.rootLogger=debug, stdout, file
log4j.debug=true

コンパイルが成功したら、実行します。

終了です。

続きはこちら
VisualStudio(VC9) でlog4cxxをつかう その3 VisualStudioのデバッグ出力へ - braintag

VisualStudio(VC9) でロギングライブラリgoogle-glogを使ってみる

log4cxxを使おうと思ったのだけれども、設定が煩雑だし、オーバースペック気味と感じたので、
簡単そうなgoogle-glogを使ってみる。

1.ダウンロード

以下のサイトからダウンロード
http://code.google.com/p/google-glog/

glog-0.3.1.tar.gzを解凍するとこんな感じ

自分は、"d:\lib"以下に解凍しました。以後はそれ前提で読んでください。

2.glogをVisualStudioでビルドする

このファイルの中から、"google-glog.sln"をダブルクリックして、VisualStudioで開く。

するとこんな感じでプロジェクトが入ってます。

とりあえず、おもむろにlibglogをリリースビルド。

"d:\lib\glog-0.3.1\Release"に、DLLとLibが出来る。


準備は完了。

3.glogをコンソールアプリから使用してみる

まずは、VisualStudioでglogを使用するための設定

メニュー->ツール->オプション->プロジェクトおよびソリューション->VC++ディレクトリ
で、インクルードファイルに"d:\lib\glog-0.3.1\src\windows"を追加

次に、ライブラリファイルに、"d:\lib\glog-0.3.1\Release"を追加


メニュー->ファイル->新しいプロジェクトを追加。
コンソールアプリ"testglog"を作って試してみる。


testglogの構成プロパティ->全般で、文字セットを"マルチバイト文字セットを使用する"に変更

testglogの構成プロパティ->リンカ->入力->追加の依存ファイルに、"libglog.lib"を追加

ソースはこれ

#include "stdafx.h"

#include <glog/logging.h>

int _tmain(int argc, _TCHAR* argv[])
{
     google::InitGoogleLogging(argv[0]);
     LOG(ERROR) << "test log error";
     LOG(INFO) << "test log info";
	 return 0;
}

そしてコンパイル。

実行結果は以下の通り

windowsプログラミングしようとすると、(MFCとか)だと、以下のエラーが出てコンパイルできない。

1>c:\lib\glog-0.3.1\src\windows\glog\log_severity.h(51) : error C2059: 構文エラー : '定数'
1>c:\lib\glog-0.3.1\src\windows\glog\log_severity.h(60) : error C2065: 'NUM_SEVERITIES' : 定義されていない識別子です。
1>c:\lib\glog-0.3.1\src\windows\glog\logging.h(1125) : error C2065: 'NUM_SEVERITIES' : 定義されていない識別子です。

その場合は、

#undef ERROR
#include <glog/logging.h>

で回避する。

以上です。細かい使い方はもっといいサイトあるのでここではVisualStudioでglogを使用するまでだけ書きました。

追記


VisualStudio2008+MFCでglogを使い倒すべくがんばってみたのですが、オプション指定がうまくいきません。(デフォルトでしか動作しない状態)
環境変数を入れると設定が無視されるどころか、動作自体しなくなるし、gflagsはまともに動作しないしで、
("ERROR: unknown command line flag 'stderrthreshold'"って表示されてしまう)
使いものにならないため、glogの使用を諦めました。
自分の力不足です。
おとなしくlog4cxxに戻ります。

さらに追記


あきらめきれずいろいろ調査したところ、
VC環境でgflagsを有効にしたい場合、
configureが使えないので"\src\windows\config.h"を手動で変更しなければいけないみたいです。

#undef HAVE_LIB_GFLAGS#define HAVE_LIB_GFLAGS

しかし、コンパイルエラーで詰んでいる状態です。

1>vlog_is_on.cc
1>c:\lib\glog-0.3.1\src\vlog_is_on.cc(53) : error C2874: using 宣言によって 'fLI::FLAGS_v' の多重宣言が発生します。
1>        c:\lib\glog-0.3.1\src\vlog_is_on.cc(53) : 'fLI::FLAGS_v' の宣言を確認してください。

公式のgoogle-glogグループでも同じ質問がありますけど、放置状態なので
もうさすがに諦めます。

往生際が悪いがさらに追記してなんとか成功

logging.h 85行目で、gflagsが"#if 0"で無条件に無効化されていたため、これを有効にしたところ、コンパイルが成功!

//#if 0
#ifdef HAVE_LIB_GFLAGS
#include <gflags/gflags.h>
#endif

やっと使えるようになりました。長い道のりだったわー。

追記:やっぱり使用中止


Windowsだからなのかマルチスレッド環境だからなのかなんなのかわかりませんが、
大量のメモリリークを起こすので、使用を中止しました。もうこれ以上は手におえません。