したらばTOP ■掲示板に戻る■ 全部 1-100 最新50 | メール | |

管理人の独り言(プログラミング関連)

1みみず★:2008/08/10(日) 23:28:15
あまりにもプログラミングの内容が増えすぎた。
よって隔離スレの中を更に隔離。

262 ◆rCEzuNnL0g:2008/09/07(日) 11:14:13
p = &c1;
0041160C lea eax,[ebp-18h]
0041160F mov dword ptr [ebp-34h],eax
p->Set(100);
00411612 mov esi,esp
00411614 push 64h
00411616 mov eax,dword ptr [ebp-34h]
00411619 mov edx,dword ptr [eax]
0041161B mov ecx,dword ptr [ebp-34h]
0041161E mov eax,dword ptr [edx+4]
00411621 call eax
00411623 cmp esi,esp
00411625 call @ILT+500(__RTC_CheckEsp) (4111F9h)

263 ◆rCEzuNnL0g:2008/09/07(日) 11:20:07
ポインタへの代入はただ単に代入しているだけだよなあ。
“ebp-34h”がオブジェクトへのポインタへ。
で、
00411621 call eax
とやっているから、この時点でeaxには関数へのポインタが入っていると。
ということは重要なのは
-----
00411616 mov eax,dword ptr [ebp-34h]
00411619 mov edx,dword ptr [eax]
0041161E mov eax,dword ptr [edx+4]
00411621 call eax
-----
だけか。

264 ◆rCEzuNnL0g:2008/09/07(日) 11:28:20
やっぱり単一継承の時は、クラスの一番アドレスの低いところに関数ポインタの配列へのポインタが入っているっぽい。

265 ◆rCEzuNnL0g:2008/09/07(日) 11:40:37
┌────────┐     ┌────────┐
│CSub1::`vftable'│────→│ 関数ポインタ │
├────────┤     ├────────┤
│  メンバ変数  │     │ 関数ポインタ │
└────────┘     ├────────┤
               │ 関数ポインタ │
               └────────┘

266 ◆rCEzuNnL0g:2008/09/07(日) 11:41:15
予想以上にずれたなあ。
メモ帳にコピーすれば綺麗に見えますよ。

267 ◆rCEzuNnL0g:2008/09/07(日) 11:42:21
結論。
単純継承の場合は何処から継承しているかは分からない。

268 ◆rCEzuNnL0g:2008/09/07(日) 11:52:53
多重継承の場合はそんなに単純ではない。
適当にペンと消しゴムのようなクラスを実装して、
ペンと消しゴムが一緒になったクラスを継承で定義してみる。
-----
CPenWithEraser c;
004115CD lea ecx,[ebp-18h]
004115D0 call CPenWithEraser::CPenWithEraser (411019h)
004115D5 mov dword ptr [ebp-4],0
IPen *pp = &c;
004115DC lea eax,[ebp-18h]
004115DF mov dword ptr [ebp-24h],eax
IEraser *pe = &c;
004115E2 lea eax,[ebp-18h]
004115E5 test eax,eax
004115E7 je main+67h (4115F7h)
004115E9 lea ecx,[ebp-18h]
004115EC add ecx,4
004115EF mov dword ptr [ebp-104h],ecx
004115F5 jmp main+71h (411601h)
004115F7 mov dword ptr [ebp-104h],0
00411601 mov edx,dword ptr [ebp-104h]
00411607 mov dword ptr [ebp-30h],edx
pp->Write("書き書き");
0041160A sub esp,20h
0041160D mov ecx,esp
0041160F mov dword ptr [ebp-0FCh],esp
00411615 mov esi,esp
00411617 push offset string "\x8f\x91\x82\xab\x8f\x91\x82\xab" (417800h)
0041161C call dword ptr [__imp_std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > (41B344h)]
00411622 cmp esi,esp
00411624 call @ILT+495(__RTC_CheckEsp) (4111F4h)
00411629 mov dword ptr [ebp-104h],eax
0041162F mov eax,dword ptr [ebp-24h]
00411632 mov edx,dword ptr [eax]
00411634 mov ecx,dword ptr [ebp-24h]
00411637 mov eax,dword ptr [edx]
00411639 call eax
pe->Erase();
0041163B mov eax,dword ptr [ebp-30h]
0041163E mov edx,dword ptr [eax]
00411640 mov esi,esp
00411642 mov ecx,dword ptr [ebp-30h]
00411645 mov eax,dword ptr [edx]
00411647 call eax
00411649 cmp esi,esp
0041164B call @ILT+495(__RTC_CheckEsp) (4111F4h)
-----

269 ◆rCEzuNnL0g:2008/09/07(日) 11:54:19
IPen*へのダウンキャストは、ただ単にポインタを代入しているだけだが、
IEraser*へのダウンキャストは、ちょっと複雑なようだ。
そこらへんをピックアップ。

270 ◆rCEzuNnL0g:2008/09/07(日) 11:55:03
IEraser *pe = &c;
004115E2 lea eax,[ebp-18h]
004115E5 test eax,eax
004115E7 je main+67h (4115F7h)
004115E9 lea ecx,[ebp-18h]
004115EC add ecx,4
004115EF mov dword ptr [ebp-104h],ecx
004115F5 jmp main+71h (411601h)
004115F7 mov dword ptr [ebp-104h],0
00411601 mov edx,dword ptr [ebp-104h]
00411607 mov dword ptr [ebp-30h],edx

271 ◆rCEzuNnL0g:2008/09/07(日) 12:12:49
ebp-104hが良く分からないが、大体構造は以下のようである。
┌─────────────┐
│CPenWithEraser::`vftable' │←IPenの関数ポインタ配列へのポインタ
├─────────────┤
│CPenWithEraser::`vftable' │←IEraserの関数ポインタ配列へのポインタ
└─────────────┘

272 ◆rCEzuNnL0g:2008/09/07(日) 12:20:31
もしもIPenやIEraserがメンバ変数を持っている場合は以下のようになる。
┌─────────────┐
│CPenWithEraser::`vftable' │←IPenの関数ポインタ配列へのポインタ
├─────────────┤
│  IPenのメンバ変数   │
├─────────────┤
│CPenWithEraser::`vftable' │←IEraserの関数ポインタ配列へのポインタ
├─────────────┤
│  IEraserのメンバ変数   │
├─────────────┤
│CPenWithEraserのメンバ変数│
└─────────────┘

273 ◆rCEzuNnL0g:2008/09/07(日) 12:22:59
つまりCPenWithEraserからIEraserへキャストするときは、
IPen用のvftableとメンバ変数分の大きさをポインタに足せばいい。
これは三つから継承しても、四つから継承しても同じ。

274 ◆rCEzuNnL0g:2008/09/07(日) 12:28:34
つまり、多重継承しているときは、ポインタを代入した積もりでも、
ポインタの値は異なっているということである。
上の例では厳密には&c != peである。
ただ、実際に
if(&c == pe){std::cout << "等しい!" << std::endl;}
とやると、&cが(IEraserに)ダウンキャストされてから比較が行われるので、
等しい!と表示される。
という事で、多重継承は遅くなる原因なので必要最低限に留めた方が良いかと。

275 ◆rCEzuNnL0g:2008/09/07(日) 12:30:24
まあ、そんなこと言ったらC++は遅いので使わないほうが良いよ、と言っているようなものだがw

276 ◆rCEzuNnL0g:2008/09/07(日) 12:38:51
これは
IHuman *ph = &c;
でIHumanがISwimmerかIClimberのどちらかが分からないからコンパイルが出来ない。
---
#include <iostream>
#include <string>

class IHuman{
public:
virtual
void
Breath() = 0;
};

class ISwimmer : public IHuman{
public:
virtual
void
Swim() = 0;
};

class IClimber : public IHuman{
public:
virtual
void
Climb() = 0;
};

class CBaka : public ISwimmer, public IClimber{
public:
virtual
void
Breath(){
std::cout << "スースー" << std::endl;
}
virtual
void
Swim(){
std::cout << "ぶくぶくぶく" << std::endl;
}
virtual
void
Climb(){
std::cout << "どっこいしょ" << std::endl;
}
};

int main(int argc, char **argv){
CBaka c;
IHuman *ph = &c;
ph->Breath();
}

277 ◆rCEzuNnL0g:2008/09/07(日) 12:40:46
このように書けばコンパイルが出来る。
があんまり意味がない気がする。
---
#include <iostream>
#include <string>

class IHuman{
public:
virtual
void
Breath() = 0;
};

class ISwimmer : public IHuman{
public:
virtual
void
Swim() = 0;
};

class IClimber : public IHuman{
public:
virtual
void
Climb() = 0;
};

class CBaka : public ISwimmer, public IClimber{
public:
virtual
void
Breath(){
std::cout << "スースー" << std::endl;
}
virtual
void
Swim(){
std::cout << "ぶくぶくぶく" << std::endl;
}
virtual
void
Climb(){
std::cout << "どっこいしょ" << std::endl;
}
};

int main(int argc, char **argv){
CBaka c;
IHuman *ph1 = (ISwimmer *)&c;
IHuman *ph2 = (IClimber *)&c;
ph1->Breath();
ph2->Breath();
}

278 ◆rCEzuNnL0g:2008/09/07(日) 12:46:14
という事で、このようなときのために仮想継承というものがある。
これで良い感じ。
-----
#include <iostream>
#include <string>

class IHuman{
public:
virtual
void
Breath() = 0;
};

class ISwimmer : public virtual IHuman{
public:
virtual
void
Swim() = 0;
};

class IClimber : public virtual IHuman{
public:
virtual
void
Climb() = 0;
};

class CBaka : public ISwimmer, public IClimber{
public:
virtual
void
Breath(){
std::cout << "スースー" << std::endl;
}
virtual
void
Swim(){
std::cout << "ぶくぶくぶく" << std::endl;
}
virtual
void
Climb(){
std::cout << "どっこいしょ" << std::endl;
}
};

int main(int argc, char **argv){
CBaka c;
IHuman *ph = &c;
}

279 ◆rCEzuNnL0g:2008/09/07(日) 12:47:42
因みに、クラス名がCBakaとなっているのは、良い名前が思いつかなかったから。
ただそれだけ。

280 ◆rCEzuNnL0g:2008/09/07(日) 12:50:14
仮想継承するとなんだか更にアセンブリコードが複雑になるなあ。
-----
CBaka c;
0041156E push 1
00411570 lea ecx,[c]
00411573 call CBaka::CBaka (4111EAh)
IHuman *ph = &c;
00411578 lea eax,[c]
0041157B test eax,eax
0041157D jne main+3Bh (41158Bh)
0041157F mov dword ptr [ebp-0ECh],0
00411589 jmp main+4Bh (41159Bh)
0041158B mov ecx,dword ptr [ebp-14h]
0041158E mov edx,dword ptr [ecx+4]
00411591 lea eax,[ebp+edx-14h]
00411595 mov dword ptr [ebp-0ECh],eax
0041159B mov ecx,dword ptr [ebp-0ECh]
004115A1 mov dword ptr [ph],ecx

281 ◆rCEzuNnL0g:2008/09/07(日) 12:52:01
因みにリリース版でビルドするとこんな感じ
-----
int main(int argc, char **argv){
00401090 sub esp,14h
CBaka c;
IHuman *ph = &c;
ph->Breath();
00401093 lea ecx,[esp+10h]
00401097 mov dword ptr [esp+4],offset CBaka::`vbtable' (402180h)
0040109F mov dword ptr [esp+0Ch],offset CBaka::`vbtable' (402188h)
004010A7 mov dword ptr [esp],offset CBaka::`vftable' (40216Ch)
004010AE mov dword ptr [esp+8],offset CBaka::`vftable' (402174h)
004010B6 mov dword ptr [esp+10h],offset CBaka::`vftable' (40217Ch)
004010BE call dword ptr [CBaka::`vftable' (40217Ch)]
}
004010C4 xor eax,eax
004010C6 add esp,14h
004010C9 ret

282 ◆rCEzuNnL0g:2008/09/07(日) 12:55:01
ん!
vbtableってなんだ?vftableなら分かるが・・・

283 ◆rCEzuNnL0g:2008/09/07(日) 13:35:43
仮想継承のコードは複雑すぎて分からない。
が結局のところ、普通の継承と同じような感じだと思っている。
眠たくなってきた。

284 ◆rCEzuNnL0g:2008/09/07(日) 13:58:06
仮想継承で意味があるのはこんなのではない。
本当に意味があるのは、この例ではIHumanにメンバ変数がある時である。
そのときにCBaka*をISwimmer*やIClimber*にダウンキャストして、
ISwimmer::メンバ変数やIClimber::メンバ変数を変更すると、両方に適用されると。
ということは、両方とも同じメンバ変数を参照するためには、色々となんか良く分からないことをやる必要がある。
まあ、実際にやってみたのだが、その補正用の値がvbtableに格納されていると思われる。
恐らくこんな感じのメモリの使われ方ではなかろうか。
+00:CBaka::`vftable' <- ISwimmer
+04:CBaka::`vbtable' <- ISwimmerのIHumanメンバ変数参照用
+08:CBaka::`vftable' <- IClimber
+0C:CBaka::`vbtable' <- IClimberのIHumanメンバ変数参照用
+10:CBaka::`vftable' <- IHuman

285 ◆rCEzuNnL0g:2008/09/07(日) 13:59:11
ISwimmerやIClimberにメンバ変数が入った場合は、
普通にvbtableの後にそれぞれ場所をとれば大丈夫である。
本当に最初に此れを考えた奴は天才だなあ。

286 ◆rCEzuNnL0g:2008/09/07(日) 14:01:46
CBakaのメンバ変数はIHumanのメンバ変数の後に追加すればよい。
IHumanのメンバ変数はvftableの後に追加すればよい。
こうすればIHumanを仮想継承していないクラスがあったとしても、
IHumanのメンバ関数は通常通りに読み出せる。

vbtableはISwimmer*からIHumanやIClimberからIHumanへのキャストへも使われる予感。

287 ◆rCEzuNnL0g:2008/09/07(日) 14:06:16
仮想継承をしたら、仮想継承したクラスはvbtableを持たねばなるまい。
例えそのクラスを他のクラスに継承しなくても、仮想継承汁!とソースに書かれている以上、用意はせねばいかん。
という事で、必要な時意外は、遅くなる仮想継承は止めましょうということです。

288 ◆rCEzuNnL0g:2008/09/07(日) 14:16:54
そういえば、コンストラクタが返す値は
自分自身の参照。
何故ならば
std::string("Yahoo!!").c_str();
という書き方が出来るから。
ポインタだと->演算しだし、参照じゃないと無駄が多い。
という事で参照。

289 ◆rCEzuNnL0g:2008/09/07(日) 14:29:22
某所でキャストの仕方について次のような奴があった。
type(...)
つまり
char c = '3';
std::cout << int(c) << std::endl;
の後の奴を型キャストとか言っている訳だ。
うん実際に試せば分かるが此れは“51”と出力される。普通に出力すると“3”である。
ただ、此れは厳密にはキャストではなくて、int型のコンストラクタが呼ばれているだけである。
つまり、int型やchar型云々にもデフォルトでコンストラクタがあるということである。
実際に以下のコードを試すと“0”と出力される。
---
std::cout << int() << std::endl;
---
勿論char()にすれば何も表示されない(何故ならば、NULL文字だから)。
試していないが、その他unsigned int()とかwchar_t()とかでも同様であろう。
つまりこれらは0で初期化される。

290 ◆rCEzuNnL0g:2008/09/07(日) 14:30:37
int *p1 = new int, *p2 = new int();
とすると
*p1は不定*p2は0である。
括弧を付けるか付けないかで此れだけ違います。

291 ◆rCEzuNnL0g:2008/09/07(日) 14:34:53
こんな風にするとウマー?
----
#include <iostream>
#include <string>

struct POINT{
int x, y;
POINT()
: x(), y()
{}
friend
std::ostream &operator<<(std::ostream &, POINT &);
};

std::ostream &operator<<(std::ostream &os, POINT &p){
return os << p.x << "," << p.y;
}

int main(int argc, char **argv){
std::cout << POINT() << std::endl;
}

292 ◆rCEzuNnL0g:2008/09/07(日) 14:37:04
中身が分からない関数の呼び出しは最適化のしようがない。
何故ならば内部で副作用があるかもしれないからである。
staticな変数があってそれが変更されて、後からの動作に影響が出るかもしれないからである。
という事で、関数の呼び出しの最適化はあまり期待しないほうがいいかもしれない。
まあ、全部そのプロジェクトから分かる範囲の関数ならばインライン化してくれるかもしれない。
JITコンパイラ的な奴を自分で組み込むのもありかもしれない。

293 ◆rCEzuNnL0g:2008/09/07(日) 14:40:19
JITコンパイラ的な奴を組み込むとなると、多分初期化に時間がかかる。
やるならば逆アセンブリして解析して、メモリ確保してコピーして埋め込んで、コピーして、
絶対アドレスがあったら修正して云々しなければならないと思う。
まあ、それをやったのが、Firefox3.1に搭載予定の、なんかよく分からん名前のやつであろう。

294 ◆rCEzuNnL0g:2008/09/07(日) 14:42:43
結構、その初期化にかかる時間は長いので、
有名ライブラリの奴をコンパイルしておけばいいと思う。
で、CRCで同じハッシュの奴はコンパイルした奴を使うと。
まあ、こういうのにGoogleが出てくるといいね。
全てのライブラリ使用者がGoogleとかからダイレクトにjQueryとかを利用すれば、
URLを見ただけで態々ダウンロードしてCRCを確かめなくてもキャッシュを利用することが出来る。
まあ、少しぐらいしか早くならない気もするけれども。

295 ◆rCEzuNnL0g:2008/09/07(日) 17:15:42
うーん
三度目ぐらいにC++0xのWikipediaの解説を読んだのだが、複雑すぎで今の僕には理解できません><

296 ◆rCEzuNnL0g:2008/09/07(日) 17:42:11
取り敢えずラムダ関数が使えるようになれば良いねえと。
[](int x, int y){return x + y}
とかうまー

297 ◆rCEzuNnL0g:2008/09/08(月) 18:59:31
プラグイン3種アップデート+SuperView を活用できる便利なスクリプトの紹介 (フェンリル | デベロッパーズブログ)
http://www.fenrir.co.jp/blog/2008/09/superview.html
---
>この FaviconCleaner プラグインは NTFS のアクセス日時を取得する API を使用している関係で Unicode 版のみの配布であり、NTFS 上にキャッシュが保存されている環境に対応します。NTFS ではない場合には何も起こりません。
------
うーん。自分はFAT32上にSleipnirを構築しているので困るなあ。
アクセス日時だったら、FATでもあるんだぜ?
Wikipediaによると
>作成(精度は10ミリ秒), 修正(精度は2秒), アクセス(精度は1日)
>(長いファイル名がサポートされている時のみ、作成時間とアクセス日付が更新できる)
と書かれている。
別に一日という精度だったら問題ないと思うんだけれどもねえ。
ちょっと頑張ってほしい。

298 ◆rCEzuNnL0g:2008/09/08(月) 19:02:37
因みにNTFSだと100ナノ秒単位で記録できるらしい。

299 ◆rCEzuNnL0g:2008/09/08(月) 19:23:59
“Hatena Bookmarker 1.1.3”の修正点について。
>タブ上でホイール回転をおこなうと常時通信が走っていた問題を修正した。(t.o)
確かに直ってますね。多分実装としては、
「選択が変わった or ページが移動した時」にスレッド生成!だけれども動かさない。
また「選択が変わった or ページが移動した時」に前のスレッドがあったらそれを殺す。
で、またスレッド生成をする。
暫く待ったら通信して結果を表示!

という感じだと思う。だから普通に変えただけでは通信までに時間がかかる。
だからキャッシュを利用すれば良いものを・・・。駄目な理由があるんですかね。
Delphiは良く分からんけれども、C++ならばstd::vector<int>とかで簡単に出来そうなんだけれども。

300 ◆rCEzuNnL0g:2008/09/08(月) 19:29:33
Black Hat Japan 2008:ブラックハットジャパン2008
http://www.blackhat.com/html/bh-japan-08/bh-jp-08-main.html
----
こんなのがあるんだ。
到底俺のいけるレベルではない。

301 ◆rCEzuNnL0g:2008/09/08(月) 20:23:52
>>299
どうやら違うっぽい。
という事で、嘘です。
まあ、通信までに時間がかかるのは本当だけれども。

302 ◆rCEzuNnL0g:2008/09/08(月) 20:37:53
プロクソミトロンでリファラーをそのページ自身に変更するのは止めたほうが良い。
リファラーの関係で色々と不味い。

303 ◆rCEzuNnL0g:2008/09/08(月) 20:41:10
スクリプトで外部サイトに不正に書き込まれる可能性が非常に高い。
つまり、ほにゃほにゃを殺すとか言う書き込みを自分の意図によらず書き込むかもしれないということ。

304 ◆rCEzuNnL0g:2008/09/08(月) 21:33:47
由々識の気まぐれ日記 SuperDrag Extension 1.0.3 Beta2a 公開
http://yuyushiki.8.dtiblog.com/blog-entry-149.html
---
>これはもう、「@Referer:」,「@Cookie:」,「@UserAgent:」を新たに追加した上で、
>Sleipnir 本体に実装しても良いのではないでしょうか。
-----
危険すぎるwwwww
「@post:」自体だけでも十分危険なのに「@Referer:」とか、「@Cookie:」までつけたら、Sleipnir死亡www
これをつけたら、リンクをクリックをしただけで2chに犯罪予告を行ってしまうリンクが書けるwww
というか、リンクをドラッグアンドドロップで持っていくと@post:で実行できるのも速攻止めるべきである。
実際に掲示板に書き込めるかは今から試してみる。

305 ◆rCEzuNnL0g:2008/09/08(月) 21:37:02
http://jbbs.livedoor.jp/computer/38153/bbs/write.cgi/computer/38153/1218378495/@post:DIR=computer&amp;BBS=38153&amp;KEY=1218378495&amp;TIME=1220877228&amp;NAME=&amp;MAIL=sage&amp;MESSAGE=test

306 ◆rCEzuNnL0g:2008/09/08(月) 21:38:20
http://jbbs.livedoor.jp/bbs/write.cgi/computer/38153/1189595822/@post:DIR=computer&amp;BBS=38153&amp;KEY=1218378495&amp;TIME=1220877228&amp;NAME=&amp;MAIL=sage&amp;MESSAGE=test

307あぼーん:あぼーん
あぼーん

308 ◆rCEzuNnL0g:2008/09/08(月) 21:42:39
という事で、出来た。
>>306をドラッグアンドドロップすればこのスレッドにtestという書き込みがなされる。
----
※書き込むと自分の記録に貴方のIPアドレスが記録されます。
 犯罪予告では有りませんが、そこらへん嫌だなあと思う方は自分の掲示板で試されることをお勧めします。
----
これがクリック一発で発動したらどうでしょうか。本文の内容を犯罪予告に変えれば一発です。
ただ、2chはクッキーとリファラーによってチェックしているので問題ないですが、もし上記のものが実装されたら、それこそひとたまりもありません。
という事で、リンクのD&Dで発動するのはセキュリティー的に不味いので止めていただきたいです。
ただ、スクリプトからの実行は良いと思うし、リンクを選択してD&Dをしたときの実行はありのほうがいいかもしれません。
ただ、此れもデフォルトoffでuser.iniで書き換えのみが一番良いと思います。

309あぼーん:あぼーん
あぼーん

310 ◆rCEzuNnL0g:2008/09/08(月) 21:49:27
http://jbbs.livedoor.jp/bbs/write.cgi/computer/38153/1189595822/#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@post:DIR=computer&BBS=38153&KEY=1218378495&TIME=1220877228&NAME=&MAIL=sage&MESSAGE=test

#を利用してリンクを長くすることが有効化のテスト。

311あぼーん:あぼーん
あぼーん

312あぼーん:あぼーん
あぼーん

313 ◆rCEzuNnL0g:2008/09/08(月) 21:59:40
有効みたいだなあ。

314 ◆rCEzuNnL0g:2008/09/08(月) 22:05:31
自分の書き込みが邪魔だから消しておこうwww

315 ◆rCEzuNnL0g:2008/09/08(月) 22:10:10
という事で、普通の人ならば分かるだろうけれども、
一応postメソッドの危険性についてブログで述べておくこととする。
-----
SuperDrag Extension 1.0.3の「@post:」について - みみず日記
http://d.hatena.ne.jp/sub_chon/20080908/1220878846
-----

316 ◆rCEzuNnL0g:2008/09/08(月) 23:05:10
まあ、こういういたずらが出来ちゃうから、掲示板はPOSTで書き込みを行うんですね。
で、XMLHttpRequestも他のドメインにアクセスできないし、リファラーも変えられないんです。
という事で、このセキュリティーの方針の逆をいくSleipnirには関心が出来ないわけである。
別にセキュリティー専門家って言うわけでもないんだけれども。

317 ◆rCEzuNnL0g:2008/09/08(月) 23:08:11
例のリンクをドラッグアンドドロップされると、俺の掲示板に書き込みが増えてうまー。
って言うわけでもない。
まあ、正直testっていう書き込みは邪魔だよね。
だけれども、セキュリティーというものは体感して初めて分かるものであると勝手に思っている。
というか、実証できないと全く意味が無いので。

318 ◆rCEzuNnL0g:2008/09/08(月) 23:10:09
つまり、机上の空論では全くの意味が無い。
こんなプログラミングが書ける、と頭の中で思っていても意味が無い。
実際に書いて書けるかが重要である。

319 ◆rCEzuNnL0g:2008/09/09(火) 19:26:01
あれれ・・・
まだ書き込めるなあ。
やっぱりリンクを開くときには「@post:」を無視するべきだと思うんだけれどもなあ。
まあ、「次のような内容を送信しようとしています」とか出たほうが良いと思うんだけれどもなあ。
選択した文字列を開くときと、スクリプトから開くは表示する必要性は無いと思うけれども。

320 ◆rCEzuNnL0g:2008/09/09(火) 21:12:32
やっぱりまだ書き込める。
ま、ドラッグしたアンカーのURLを確認しないユーザーの自己責任といえば、自己責任だよなあ。
ただ、ブラウザでページを開こうとする動作、ということになっているので、さすがに無視できないと思う。

321 ◆rCEzuNnL0g:2008/09/10(水) 18:20:19
うーん。
ページ移動中に検索バーに検索文字列を入力することがあるのだが、
そのときに、HTMLのページにフォーカスを移動させる命令があると、勝手にそっちに移動してしまう。
URLバーとか検索バーにフォーカスがあるときは移動させて欲しくないなあ。
特に入力中は絶対に止めてほしい。

322 ◆rCEzuNnL0g:2008/09/10(水) 18:21:13
やっぱり、人が着てないと思うと、書き込みやすいね。
アクセス解析を入れたけれども、全然きていないのが、良くわかる。
これからも色々と解析していきたいと思う。

323 ◆rCEzuNnL0g:2008/09/10(水) 18:41:47
逆アセンブリって、仕様によって全然書きたかが違う。
mov A, B
とか書いても
A->BかB->Aかは違ったりする。

324 ◆rCEzuNnL0g:2008/09/10(水) 20:01:16
やっぱり、仮想継承で生成されるアセンブリが解読できないのは悔しいので、
今解読中・・・

325 ◆rCEzuNnL0g:2008/09/10(水) 20:07:05
仮想継承をすると、一つ引数をプッシュするようである。何故か
CSub<-ISub1<-ISuper
└<---ISub2<---┘
上のように継承しているとか仮定する。

326 ◆rCEzuNnL0g:2008/09/10(水) 20:09:43
ISub1を実体化するときに、
ISuperのコンストラクタはISub1が呼ばねばならない。
ISub2を実体化するときに、
ISuperのコンストラクタはISub2が呼ばねばならない。
CSubを実体化するときに、
ISub1とISub2のコンストラクタはCSubを呼ばねばならない。
が、そのISub1,2のコンストラクタでISuperのコンストラクタは呼んではならない。
よってそのためのフラグである。

327 ◆rCEzuNnL0g:2008/09/10(水) 20:11:09
つまり、仮想継承元を実体化しなくてはならないときには、
最後の引数にtrue(1)を、
実体化しなくてもよいときは、
最後の引数にfalse(0)を、
置くということである。

328 ◆rCEzuNnL0g:2008/09/10(水) 20:20:20
大体予想通りのメモリ配置だなあ。

+00:offset CSub::`vftable'
+04:offset CSub::`vbtable' -> offset ISub1::`vbtable'
+08:m_v1
+0C:offset ISub2::`vftable' -> offset CSub::`vftable'
+10:offset CSub::`vbtable'
+14:offset ISub2::`vftable'
+18:offset IClass::`vftable'
+1C:m_v2
+20:offset CSub::`vftable'
+24:offset ISub1::`vftable'
+28:m_1
+2C:m_2
+30:m_3

329 ◆rCEzuNnL0g:2008/09/10(水) 20:23:53
という事で、これでunequalとなります。
----------
if((void*)pcs == (void*)(ISuper*)pcs){
std::cout << "equal" << std::endl;
}else{
std::cout << "unequal" << std::endl;
}

330 ◆rCEzuNnL0g:2008/09/10(水) 20:36:39
+00:offset ISub1::`vftable' -> offset CSub::`vftable'
+04:offset CSub::`vbtable'
+08:m_v1
+0C:offset ISub2::`vftable' -> offset CSub::`vftable'
+10:offset CSub::`vbtable'
+14:m_v2
+18:offset IClass::`vftable' -> offset ISub2::`vftable'
+1C:
+20:
+24:offset ISub1::`vftable' -> offset CSub::`vftable'
+28:m_1
+2C:m_2
+30:m_3

331 ◆rCEzuNnL0g:2008/09/10(水) 20:49:39
>>328,330
は両方とも間違えだと思う。
なんだか面倒になってきた。
やっぱり仮想継承は考えないこととするか。

332 ◆rCEzuNnL0g:2008/09/10(水) 20:53:29
まあ、補正用にvbtableが入るのは間違いない。
検証用に用意した、適当なソースコードでも貼っておく。
-----

#include <iostream>
#include <string>

class IClass{
public:
virtual
~IClass(){}

virtual
int Get() = 0;

int m_1;
int m_2;
int m_3;
};

class ISub1 : virtual public IClass{
public:
virtual
~ISub1(){}

int m_v1;

virtual
int Get1() = 0;
};

class ISub2 : virtual public IClass{
public:
virtual
~ISub2(){}

int m_v2;

virtual
int Get2() = 0;
};

class CSub : public ISub1, public ISub2{
public:
virtual
int Get1(){
return m_v1;
}
virtual
int Get2(){
return m_v2;
}
virtual
int Get(){
return m_1;
}
};

int main(int argc, char **argv){
CSub cs;
CSub *pcs = &cs;

pcs->m_1 = 0;
pcs->m_2 = 0;
pcs->m_3 = 0;
pcs->m_v1 = 0;
pcs->m_v2 = 0;

if((void*)pcs == (void*)(IClass*)pcs){
std::cout << "equal" << std::endl;
}else{
std::cout << "unequal" << std::endl;
}

/*
ISub1 *pi1 = &cs;
ISub2 *pi2 = &cs;
IClass *pic = &cs;

pcs->m_1 = pi1->m_1 = pi2->m_1 = pic->m_1 = -1;
*/
};

333 ◆rCEzuNnL0g:2008/09/10(水) 20:55:00
デザインパターン編 第22章 Visitorパターン
http://www.geocities.jp/ky_webid/design_pattern/022.html
-----
Visitorパターンは物凄く使えると思う。

334 ◆rCEzuNnL0g:2008/09/10(水) 20:58:35
つまりLispを実装しようと思ったら、
全てのCellとかAtomとかをILispObjとかにして、
そっから全てのObjectを継承して、
ILispObj::Eval(IVisiter);
とかやって、
IVisiter::Printとかやったればいいんじゃね?とか妄想している。
正直上手くいきそうに無いwwwww

335 ◆rCEzuNnL0g:2008/09/10(水) 21:32:19
寝るか「、¥

336 ◆rCEzuNnL0g:2008/09/10(水) 22:48:01
仮称継承して出力してみた。
-----
序数: 0001 名前: ??0CSub1@@QAE@ABV0@@Z
序数: 0002 名前: ??0CSub1@@QAE@XZ
序数: 0003 名前: ??0CSub2@@QAE@ABV0@@Z
序数: 0004 名前: ??0CSub2@@QAE@XZ
序数: 0005 名前: ??0CSub@@QAE@ABV0@@Z
序数: 0006 名前: ??0CSub@@QAE@XZ
序数: 0007 名前: ??0CSuper@@QAE@ABV0@@Z
序数: 0008 名前: ??0CSuper@@QAE@XZ
序数: 0009 名前: ??1CSub1@@UAE@XZ
序数: 000A 名前: ??1CSub2@@UAE@XZ
序数: 000B 名前: ??1CSub@@UAE@XZ
序数: 000C 名前: ??1CSuper@@UAE@XZ
序数: 000D 名前: ??4CSub1@@QAEAAV0@ABV0@@Z
序数: 000E 名前: ??4CSub2@@QAEAAV0@ABV0@@Z
序数: 000F 名前: ??4CSub@@QAEAAV0@ABV0@@Z
序数: 0010 名前: ??4CSuper@@QAEAAV0@ABV0@@Z
序数: 0011 名前: ??_7CSub1@@6B@
序数: 0012 名前: ??_7CSub2@@6B@
序数: 0013 名前: ??_7CSub@@6B@
序数: 0014 名前: ??_7CSuper@@6B@
序数: 0015 名前: ??_8CSub1@@7B@
序数: 0016 名前: ??_8CSub2@@7B@
序数: 0017 名前: ??_8CSub@@7BCSub1@@@
序数: 0018 名前: ??_8CSub@@7BCSub2@@@
序数: 0019 名前: ??_DCSub1@@QAEXXZ
序数: 001A 名前: ??_DCSub2@@QAEXXZ
序数: 001B 名前: ??_DCSub@@QAEXXZ
序数: 001C 名前: ?Print@CSub1@@UAEXXZ
序数: 001D 名前: ?Print@CSub2@@UAEXXZ
序数: 001E 名前: ?Print@CSub@@UAEXXZ
序数: 001F 名前: ?Print@CSuper@@UAEXXZ

337 ◆rCEzuNnL0g:2008/09/10(水) 23:06:42
メンバ変数にメンバ関数へのポインタを置いておいて、状態によってその呼び出す関数を変えたい。
で、こんな書き方しか出来ないのだろうか?
---
#include <iostream>
#include <string>

class CClass{
public:
void (CClass::*pFunc)();
std::string str;

CClass()
: pFunc(NULL)
, str("")
{}

void Print1(){
std::cout << str << std::endl;
}
void Print2(){
std::cout << "|" << str << "|" << std::endl;
}

void Set(std::string _str){
str = _str;
}
};

int main(int, char**){
CClass e;
e.pFunc = &CClass::Print1;
(e.*(e.pFunc))();
}

338 ◆rCEzuNnL0g:2008/09/10(水) 23:07:59
(e.*(e.pFunc))();
とか正直何がしたいのか分からない。というかeを二回書いている時点でスマートじゃない。

339 ◆rCEzuNnL0g:2008/09/10(水) 23:10:09
メンバ関数内ならば、
(this->*pFunc)();
と書けるか・・・

340 ◆rCEzuNnL0g:2008/09/10(水) 23:11:42
まあ、此れで現状のC++については勉強しつくした感がある。

341 ◆rCEzuNnL0g:2008/09/10(水) 23:16:37
いや、まだ、メンバ関数ポインタについては勉強できていないな。

342 ◆rCEzuNnL0g:2008/09/10(水) 23:28:49
どうやらメンバ関数ポインタ用に新たな関数を生成するらしい。
-----
IClass::`vcall'{0}':
00412330 mov eax,dword ptr [ecx]
00412332 jmp dword ptr [eax]
-----

343 ◆rCEzuNnL0g:2008/09/10(水) 23:32:27
つまり、メンバ関数ポインタを使うと動作が遅くなるということ。

344 ◆rCEzuNnL0g:2008/09/10(水) 23:42:01
virtualな関数を持つクラスを多重継承したときに、ずれたポインタでthisを渡さなければいけないときは、
ちゃんとずらして渡しているんだなあと。

345 ◆rCEzuNnL0g:2008/09/10(水) 23:42:32
本当にコンパイラは、勝手に色々なことをしてくれますねえ。

346 ◆rCEzuNnL0g:2008/09/11(木) 00:45:59
東方とかデバッグどうしているんだろうね。
クリアーできないステージとか作っちゃわないのかなあ。

347 ◆rCEzuNnL0g:2008/09/11(木) 01:29:32
東方の弾って、基本撃ったらまっすぐ飛んでいるよね?
敵の弾の話だけれども。

348 ◆rCEzuNnL0g:2008/09/11(木) 02:52:14
Firebug Lite
http://getfirebug.com/lite.html
----
こんなのがあったんだ。

349 ◆rCEzuNnL0g:2008/09/11(木) 20:18:44
Sleipnirは
MFC + COM

350 ◆rCEzuNnL0g:2008/09/12(金) 19:09:17
PEInfo: PE Structure information

( base data )
entrypointaddress.: 0x1000a127
timedatestamp.....: 0x48b4c771 (Wed Aug 27 03:18:09 2008)
machinetype.......: 0x14c (I386)

( 5 sections )
name viradd virsiz rawdsiz ntrpy md5
.text 0x1000 0x9bc5 0xa000 6.08 33b42c7206c4f31e757a883ec2547f8c
.rdata 0xb000 0x30c6 0x4000 4.16 43c0b6753432e49b0bf939cf053250ad
.data 0xf000 0x778 0x1000 1.28 495ef169b5b15996b1839f1a943b45b0
.rsrc 0x10000 0x1ac 0x1000 3.46 7fda13786a06da6ad8e043a471a7124c
.reloc 0x11000 0xcba 0x1000 5.90 ea947a48fd3e02547711ad6622936bd6

351 ◆rCEzuNnL0g:2008/09/12(金) 19:21:41
処理時間の取得方法
http://www14.big.or.jp/~ken1/tech/tech19.html

352 ◆rCEzuNnL0g:2008/09/12(金) 19:28:28
(新)APIから知るWindowsの仕組み---目次:ITpro
http://www.itproexpo.jp/article/COLUMN/20070129/259838/

353 ◆rCEzuNnL0g:2008/09/12(金) 19:51:40
EncodePointer Function (Windows)
DecodePointer Function (Windows)

354 ◆rCEzuNnL0g:2008/09/12(金) 20:00:50
?QueryInterface@FActionData@@UAGJABU_GUID@@PAPAX@Z
?QueryInterface@FByteArrayInputStream@@UAGJABU_GUID@@PAPAX@Z
?QueryInterface@FByteArrayOutputStream@@UAGJABU_GUID@@PAPAX@Z
?QueryInterface@FCmdUI@@UAGJABU_GUID@@PAPAX@Z
?QueryInterface@FFileInputStream@@UAGJABU_GUID@@PAPAX@Z
?QueryInterface@FFileOutputStream@@UAGJABU_GUID@@PAPAX@Z
?QueryInterface@FGZip@@UAGJABU_GUID@@PAPAX@Z
?QueryInterface@FHistoryData@@UAGJABU_GUID@@PAPAX@Z
?QueryInterface@FOptionDialogData@@UAGJABU_GUID@@PAPAX@Z
?QueryInterface@FSearchEngine@@UAGJABU_GUID@@PAPAX@Z
?QueryInterface@FSearchItemCombo@@UAGJABU_GUID@@PAPAX@Z
?QueryInterface@FSearchItemList@@UAGJABU_GUID@@PAPAX@Z
?QueryInterface@FStatusBarItemData@@UAGJABU_GUID@@PAPAX@Z
?QueryInterface@FToolBarButtonData@@UAGJABU_GUID@@PAPAX@Z
?QueryInterface@FToolBarButtonDataEx@@UAGJABU_GUID@@PAPAX@Z

355 ◆rCEzuNnL0g:2008/09/12(金) 20:03:29
沈黙を破ったホリエモン,ITを語る:ITpro
http://itpro.nikkeibp.co.jp/article/Interview/20080910/314505/

356 ◆rCEzuNnL0g:2008/09/12(金) 20:47:27
暇だったからCOMっぽいものを実装した。
まあ、あんまり意味が無いから削除。

357 ◆rCEzuNnL0g:2008/09/12(金) 20:47:47
あんまり完成しても感動しなかった。

358 ◆rCEzuNnL0g:2008/09/12(金) 21:15:11
DLLは・・・
エクスポートしたい全ての関数を持つ純仮想関数を持つクラスを宣言する。
でそれを継承した奴で中身のクラスを実装する。
中身のクラスをnewして純仮想関数を持つクラスにキャストして渡す関数をエクスポートする。
それをDeleteする関数をエクスポートする。

EXEは・・・
中身(中略)関数を呼び出す。
それで普通に->で関数を呼び出す。
要らなくなったら、それを(中略)関数で消す。

此れだと、出力したいClassのサイズが分からなくても大丈夫なので、絶対安心。
だからCOMとかは、バージョンが上がって新しいclassが一杯出るわけである、と某所で書いてあった。
まあ、詳しくは自分で調べてくだせう。

359 ◆rCEzuNnL0g:2008/09/12(金) 21:41:30
COM総合研究所 - COM研究室
http://www5.plala.or.jp/atata/com/
---
という事で実際のCOMの実装でも見てみるか。

360 ◆rCEzuNnL0g:2008/09/12(金) 21:56:08
え・・・
クラスのメンバー関数が__stdcallってどういうこと・・・?

361 ◆rCEzuNnL0g:2008/09/12(金) 22:04:42
結局今の僕には理解できませんでした。


新着レスの表示


名前: E-mail(省略可)

※書き込む際の注意事項はこちら

※画像アップローダーはこちら

(画像を表示できるのは「画像リンクのサムネイル表示」がオンの掲示板に限ります)

掲示板管理者へ連絡 無料レンタル掲示板