2016/07/18(Mon)双2次フィルタでLPF (他)

LPFがほしくて。

工学部だけど、アナログな信号処理とかぜんぜん勉強したことなくて、
解析学とかもまったく苦手だった情報系出身なので、
なんかLPFのサンプルプログラムとか見ても、パラメータをどう求めればいいかよくわかんなくて、
つまりどうすれば目的の関数が得られるだってばよ? 状態だったんだけど、

色々情報を探してさまよううちに↓のページを見つけて
http://www.g200kg.com/jp/docs/makingvst/04.html

RBJ Audio-EQ-Cookbook っていう つよい文書があって、つまりこれでLPFが作れるってことらしい。
理解度はやはりイマイチだけど、とりあえず低音が取り出せるようになった。
リンク先を見るに、HPFとかBPF、EQとかも作れるっぽい。便利。
今回は目的が別のところにあるので、勉強はここまでにして先に進めよう。

以下、とりあえず試したくて即席で書いたソース。

続きを読む

2016/06/16(Thr)LoadLibraryに渡されたDLLのパスをデバッガで見る x86

はてブ数 2016/06/16 1:05 プログラミング::C++ つーさ

ロードされるDLLの一覧がほしいだけなら Dependency Walker 上で、プロファイリングすれば十分なのだけど。

Kernel32.dll は、すべてのプロセスで同じアドレス空間にロードされているため、
あるプログラムで、Kernel32.dll の API に対してGetProcAddress して得た関数アドレスは、実は他のプロセスでも有効。
これを利用して、LoadLibrary に渡される文字列をデバッガから調べてみることにする。

まずは、適当なプログラム(x86)で、LoadLibraryA と LoadLibraryW を GetProcAddress して、アドレスを調べておく。
調べた結果、それぞれ 0x7639A840 と 0x763A4BF0 だった。

デバッグ対象のEXEをVisual Studioでソリューションとして開き、「デバッグ→ステップイン」でプロセスを開始する。
EXEのエントリポイントで止まるので、この状態で「デバッグ→ウィンドウ→逆アセンブル」を開き、
アドレスに先ほど得た 0x7639A840 を、アドレスとして入力しLoadLibrary の先頭にブレークポイントを仕掛ける。
同様に 0x764A5BF0 にもブレークポイントを仕掛ける。

F5で実行を再開。
ブレークしたときLoadLibraryの先頭にいる。
x86の関数呼び出し規約によれば LoadLibrary の第1引数は、ESPレジスタの指しているアドレス+4の位置に格納されている。
LoadLibraryの第1引数はロードしたいDLLへのパスを格納している文字列へのポインタなので、
これを得るための式をウォッチウィンドウに追加することで、何を引数に関数が呼ばれたかがわかる。

  (char**)(@esp+4) ← LoadLibraryAが呼ばれたとき
  (wchar_t**)(@esp+4) ← LoadLibraryWが呼ばれたとき

結果。*1

debugloadlibrary.png

というようなことをやっていた。
↑のDSPプラグインを他のアプリから使いたかったんだけど、うまく動かないやつがあってどうしてだろうと思って。

ちなみに、ESPレジスタで思い出したけど、
上記のように関数が呼び出されたとき、ESPレジスタの指す先にはリターンアドレスが入っているので、
これを使うことで、関数の呼び出し元のアドレスを得て メモリリークの追跡もできたりした。
過去形なのは最近x64が台頭しつつあるから。*2

void *my_alloc(void *pCaller, size_t size) { ... }

#define NAKED __declspec(naked)
#define WITH_CALLER(...) { void *CALLER; { __asm mov eax, [esp] __asm push ebp __asm mov ebp, esp __asm mov CALLER, eax } __VA_ARGS__;  { __asm pop ebp __asm ret } }

NAKED void * operator new(size_t size) WITH_CALLER(my_alloc(CALLER, size));
// WITH_CALLER の 展開後イメージ
__declspec(naked) void* operator new(size_t size)
{
	void* pCALLER; 
	__asm mov eax, [esp];    // 関数が呼び出された瞬間、ESPの指す先にあるリターンアドレスをEAXにメモ。
	__asm push ebp;            // VC++ がローカル変数へのアクセスをEBPを元に行うコードを生成するので、
	__asm mov ebp, esp;        // それと互換するようにEBPを準備する。
	__asm mov pCALLER, eax;      // メモったリターンアドレスをローカル変数へ移して
	my_alloc(pCALLER, size);     // それを使って本命の関数呼び出し。
	__asm mov esp, ebp;        // 使ったものは
	__asm pop ebp;             // 戻しておこう
	__asm ret;               // my_alloc の戻り値がEAXに入ってるはずなので、それがそのまま戻る。
}

my_alloc は呼び出し元のアドレスをつけて呼び出されるので、線形リストなどに時刻・サイズ等とともにメモっておけばよい。
ビルド時 .map ファイルや、逆アセンブルを出力しておけば、__FILE__などなくとも関数を特定できるのでこれで十分。

*1 : ついでにスタックのメモリも覗いてみる。

*2 : x64ではVC++はx64ではインラインアセンブラが書けないので別のやり方が必要

2014/09/27(Sat)template <T> struct intrusive_tree_base

はてブ数 2014/09/27 1:45 プログラミング::C++ つーさ

だいぶ前に書いたC++で木構造どうしようの記事
template <class T> class TreeNode { ... }; の中身は?

template<T>
struct TreeNode {
  TreeNode<T> *parent, *child_left, *child_right;
}

とかつくったら、
TreeNode<OBJECT_T *> pObject; の子供のメンバにアクセスするたびに
static_cast<OBJECT_T *>(pObject->child_left)->SomeMember;
みたいに static_cast すんのか?

という疑問に対する一つの答えが

template<T>
struct intrusive_tree_base<T>
{
  T *parent, *child_left, *child_right;
}

struct SomeTreeNode : public intrusive_tree_base<SomeTreeNode>
{
  SomeType SomeMember;
};

すればいいじゃないということに気づいた。

というわけで、実際に実装してみた。

intrusive_tree_base
https://gist.github.com/ttsuki/5b0498518f99f1fd2b78

C++11を学ぶにつれて、だんだんこういうかゆいところにも手が届くように、なってきたりする。

2013/12/21(Sat)template <class T> class TreeNode { ... }; の中身は?

はてブ数 2013/12/21 18:42 プログラミング::C++ つーさ

tree を作ることを考える。

根があって、任意数の子をとれる。
子も任意数の子をとれる。

汎用的なtreeクラスの節、template class Node 中身; の中身について考える。

どうやったら引き回しやすいか。

まぁ、複数の子っても、たくさんの子を持つか、
あるいはまったく子を持たないかわからないので、
二分木で表現することにする。

思いつくまま定義を書くと、

template<class TValue>
class Node
{
  TValue value;
  Node<T> *parent, *firstChild, *nextSibling;
};

みたいになって、それを実装してみたのが
https://gist.github.com/ttsuki/95ceef4cacdc9c5e0294 なのだけど、
いざ使ってみようと思って、
使う側に回ってからTValueにあたる型を作ってて思ったんだけど、

普通、Treeで何らかの構造を表そうと思ったら、
その要素TValueはデータ構造的にツリーになる前提があるわけで
TValue自身がTValue::ナントカ() が自分の親・兄弟にアクセスできないと、
トラヴァーサルしにくいなーということに後から気づいた。

じゃあ、

class 実際に扱いたい型 : public Node<実際に扱いたい型 *>
{
  ctor()
    : Node(this)
  {
  }
  
};

なら?
にしても、parentは、Node<TValue *>の型であって、
それをTValueとして扱うにはダウンキャストがいるのでなんか気持ち悪い。
って考えてると、

class 実際に扱いたい型
{ 
  Node<実際に扱いたい型 *> link;
  ctor()
    : link(this)
  {
  }
};

になって、マジで?ってなる。

これだと、でもまぁ、これだとキャストなしに、
自分の親ノードを得るのに return link.parent.value; できるので……。

ただ、GetParent() とか、ApplyAllChildren等を
全部pImplばりに再実装しないといけなくて、

それめんどくさいなぁ。

なんか、お約束のレシピはないのかしら。

2013/11/04(Mon)template <class T> struct Hoge { }; の T を POD に制約したい

はてブ数 2013/11/04 16:38 プログラミング::C++ つーさ

タイトルの通り、template struct Hoge ; の T を POD に制約したい。

というわけで、 Hoge がインスタンス化されようとするとき
コンパイルエラーを生成できるような、PRECONDITIONAL_ERROR なるものを作ってみた。
STATIC_ASSERTの親戚のような感じで使えるかなー。

今回作ってみたのは、template実体化時にTがPODじゃないとコンパイルエラー。
ついでに、引数に渡された配列の長さがある一定以上ないとコンパイルエラー。

自作コンテナを作るとき、TがPODならコンストラクタもデストラクタも呼ばなくてよいので、
コンテナを clear するときも、for (int i = 0; i < size(); i++) this[i]->~T(); する必要が無いっていう。

以下 gist

続きを読む

2013/11/04(Mon)C++98 C++03 の POD

はてブ数 2013/11/04 16:21 プログラミング::C++ つーさ

独自コンテナ template struct Container のTがPODだと、
メンバ追加時にコンストラクタもデストラクタも呼ばなくてよい。
コンテナを clear するときも、for (int i = 0; i < size(); i++) this[i]->~T(); する必要が無い。

では、型をPODとして定義するにはどうすればいいのかという話だ。

C++11の情報ばかりヒットして、
C++03までのPODについて、いまいちまとまった情報が得られないので、
自分なりに調べた情報をまとめておく。

続きを読む

OK キャンセル 確認 その他