関数ポインタから関数名を取得する@VC++

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
VC++でデバッグ中、関数ポインタをデバッグ画面に入れると
値のとこに関数名出るじゃないですか。
あと、チューニング作業でprofilerってアプリあるじゃないですか。
関数ごとの実行回数計測するやつ。あれでも関数名出ますよね。
ああいうの、自分でもやりたいんですよね。書き出したりとかしたいんです。
なんとかなんないすか?
2デフォルトの名無しさん:2009/01/31(土) 21:33:05
研究員の皆さん今晩は。
あいちゃんです。
何か質問はありますか?
3デフォルトの名無しさん:2009/01/31(土) 21:34:21
>>1の通りなんですが・・・
4デフォルトの名無しさん:2009/01/31(土) 21:35:58
>>1に追加しますが
関数名を取得する対象の関数には手を加えられませんよ。
5デフォルトの名無しさん:2009/01/31(土) 21:43:27
どこにでもルールってものがあるじゃないですか。
ここにもローカルルールってものがありますよね。
「あらゆる質問はまず「すれ立てるまでもない質問はここで」スレにしてください。」
って掲示板のトップに書いてありますよね。
なんとかなんないすか?


61:2009/01/31(土) 21:46:56
おれがググった結果だいたいの道筋としては

1. 使ってるDLLからシンボルとかいうのを抜き出してリストにする
2. 関数ポインタをたよりにその関数名を示すシンボルを抜き出す
3. 関数名に変換(これは専用の関数があるっぽい)

という感じでしょうか?1.はなんとかなるかもですけど、2.がさっぱりわからんです
71:2009/01/31(土) 21:48:35
>>5
これはでかい問題だと思います。
一度2chで立って未解決で終わってるっぽいです。
ネットでググっても英語でも見付からんです。
総力を結集すべくスレにしましたよ。
8デフォルトの名無しさん:2009/01/31(土) 22:09:30
ルールも守れない奴には教える事はできない
9デフォルトの名無しさん:2009/01/31(土) 23:36:54
このスレッドは天才チンパンジー「アイちゃん」が
言語訓練のために立てたものです。

アイと研究員とのやり取りに利用するスレッドなので、
関係者以外は書きこまないで下さい。

                  京都大学霊長類研究所
101 ◆0bNY21/WAs :2009/01/31(土) 23:49:17
自己解決しました。
思っていたほど大きな問題ではなく
おれレベルだとすぐに解決しました。
念のためトリップをつけておきます。
11デフォルトの名無しさん:2009/02/01(日) 00:53:33
>>10
そのとおりだよ。
お前のレベルならスレ立てなくても解決できたことは想像に難くない。
だからスレ立てるなって言われただけだ。
121:2009/02/01(日) 06:36:15
>>10
いや、こいつニセモノ
13デフォルトの名無しさん:2009/02/01(日) 10:38:06
これなんかどうよ?

Binary Hacks
ttp://www.oreilly.co.jp/books/4873112885/

VC環境じゃないけどさ
141:2009/02/01(日) 10:45:29
紹介乙。
しかし、VCじゃないのか。それじゃ仕事で使えない。
それになんかその本レベル高そうだな。
ちなみに、Linuxでは普通にできるらしい。
外国のサイトでチラっと見た。
151:2009/02/01(日) 11:05:33
Googleブックサーチで読めるなぁ。
用語解説はありがたい。
ttp://books.google.co.jp/books?id=Jzv3L2j6oqsC
161 ◆0bNY21/WAs :2009/02/01(日) 11:11:45
おいおい。
トリップなしで本物なんて言ってる偽者はなんなの?死ぬの?
171:2009/02/01(日) 11:18:40
*.lib,*.dllファイルから関数のシンボル情報を得る方法CommentsAdd Star
http://d.hatena.ne.jp/Seasons/20080928/1222587606

>>6の1.はこれで良さそう
18デフォルトの名無しさん:2009/02/01(日) 11:19:38
用途は何なの?
ビルドの時に、デバッグ情報を出力するとか、マップファイルを出力するとか選べるハズで、これらで充分だと思うんだけど。

http://msdn.microsoft.com/ja-jp/library/cc429018.aspx
とか使ってみたの?

シンボルって用語を知ってれば、こんなスレ立てずに済んだのにね!
知らなくてもくだ質で充分だったはずだけどね!

じゃあ削除依頼しといてね!
191:2009/02/01(日) 11:33:53
用途はですね
ある動作をさせてトラブルがあった場合
そのトラブル時に呼び出した関数を全部一覧して出力します。
で、その問題の動作と類似する正常な動作をさせてこれについても関数名を出力し
比較するわけなんですよ。こうすればデバッグの時のヒントになるでしょう。

*.mapや*.pdbは見たことありますけど、そういや中身までは見てないです。
*.mapはプロファイルの時に使って覚えてます。
*.pdbはブレークポイントとか貼るのに必要だったかな。それくらいです。
201:2009/02/01(日) 11:41:24
シンボルって言葉はキーワードだなとは思ってましたけど
実体がどういうものなのかよく分からなかったです。
先ほど上で紹介された本を見ると

bar::foo() => _ZN3Foo3BarE

というような変換が名前マングル(name mangling)というもので
この時右にあるような文字列がシンボルらしいです。
で、その逆

_ZN3Foo3BarE => bar::foo()

がデマングル(demangle)らしいです。

>>18
そのサイトは今なぜか見れないんであとで見ときます
211:2009/02/01(日) 11:50:54
あ、見れました。ということは

1. SymGetSymFromAddrを使い関数ポインタからシンボルを取得する
2. UnDecorateSymbolNameを使いシンボルを関数名に変換する
3. 関数名を書き出す

ということでいいんですね。
やっほ〜い
22デフォルトの名無しさん:2009/02/01(日) 12:20:44
21/1000で解決か
231:2009/02/01(日) 13:49:22
スレタイの件については解決した。
が、まだ、俺としては課題もある。
あるmainの関数を経由して実行された全ての関数を書き留める、となると難しい。
その場合>>13にあるようなコードをはさんで再コンパイルしないといけない。
しかし、あれはVC++環境の話じゃないらしいし。
でも、プロファイラーができてるわけだし、何か方法があるんだろう。

24デフォルトの名無しさん:2009/02/01(日) 14:17:37
関数がマシン語レベルでどう呼び出されてるかも知らないのか・・・
25デフォルトの名無しさん:2009/02/01(日) 14:27:05
こうして単発スレが正当化されていくのか・・・
261:2009/02/01(日) 19:00:41
>>24
アセンブラならともかく機械語のこと知ってる香具師はあんまいないでしょ
俺はアセンブラは基本情報の疑似言語問題やった程度
27デフォルトの名無しさん:2009/02/02(月) 04:49:30
スタックみろよ
28デフォルトの名無しさん:2009/02/02(月) 08:15:35
>>1
各関数の入り口でprintfすればいいと思います。
2918:2009/02/02(月) 10:51:17
>>26
アセンブラを知ってれば、"機械語は調べれば分かる"ということを知ってるはずだ。

>>23
> でも、プロファイラーができてるわけだし、何か方法があるんだろう。
あるよ。
コンパイラに手を入れるか、exe を書き換えちゃう。
特定の時点までに経由したということなら >27 でおk。

解決したので削除依頼よろしくね。
30デフォルトの名無しさん:2009/02/03(火) 16:31:17
__func__
31デフォルトの名無しさん:2009/02/03(火) 16:53:43
>>29
糞の分際で偉そうにするな
32デフォルトの名無しさん:2009/02/04(水) 00:08:25
お前より糞の方が偉いから仕方が無い
33デフォルトの名無しさん:2009/02/05(木) 11:59:24
いくら偉くても糞じゃ汚いだけだよなぁ
34デフォルトの名無しさん:2009/02/05(木) 12:34:59
その糞 (とは思えんが) より無能な >>31 の立場がない。
351:2009/02/07(土) 07:32:29
まだ終わらんよ
>>21の方法だけど
関数の使い方が分からんかった。
依存関係がないのかな。
includeして使えんかったわ。
まぁ、主なコマンド関数は別の方法で書き出すことにしたけど。
361:2009/02/07(土) 07:33:45
>>28
関数の入口に手加えられないです。
いじることができるのは関数の呼出元だけです
371:2009/02/07(土) 07:35:18
>>27
呼出元でスタック見てもしょうがなくね?
結局、呼び出す関数のポインタが分かるだけ。
381:2009/02/07(土) 07:37:40
>>30
それも呼出元で使ってもしょうがないよな
39デフォルトの名無しさん:2009/02/07(土) 16:14:18
どう使うのよ。
try {} catch ( ... ) { dump_stack_trace(); }
みたいに使うの?

まともに説明も出来なければ問題も分析できない無能な人ね。
単発スレを立てるわけだ。
401:2009/02/07(土) 17:54:26
>>19に書いてますよ
411:2009/02/07(土) 17:57:27
メインルーチンでコールバック関数を呼び出すところがあるんです。
そのコールバック関数はそれぞれ小さな処理なわけで
いろいろな場所からON_COMMAND経由で呼ばれてきます。
そいつの呼出履歴を全部分かるように出力できれば
正常な動作の呼出履歴と比較してどの処理が足りなかったのか
もしくは余分だったのか分かるじゃないですか。
42デフォルトの名無しさん:2009/02/07(土) 18:01:13
>分かるじゃないですか
なんだ、只の阿呆か。
そもそもそんなことしなくても履歴を手繰る方法はあるしね。
431:2009/02/07(土) 18:24:42
落ちるような処理だったら落ちたとこのコールスタックを記録しとけばいいでしょうが
落ちずに一見正常に動作するから厄介なんです
44デフォルトの名無しさん:2009/02/07(土) 20:51:50
でさ、その ON_COMMAND はなんのフレームワークなの?
自分で作ったの?

自分で作ったんなら、その我々には皆目見当も付かない ON_COMMAND が
関数ポインタ経由で呼び出すときにその関数のアドレスを map ファイルから
辞書引きしたらいいんじゃないの?

っていうか、これもくだ質でいいよね。

19 に書いてあるって、わかるわけねーよ。無能は気楽でいいよ。
ロギングなら、ログ取りたい人の責任でやることだしロギングライブラリ探すべきでしょ普通。
45デフォルトの名無しさん:2009/02/07(土) 23:32:32
>>44
単発の質問のスレで答えようとしなくていいよ。
461:2009/02/08(日) 08:43:44
>>44
MFCのことじゃないですか。ここはVC++のスレですよ。
mapファイルに書いてあるアドレスにいつも必ず決まった関数を配置するの?
関数の配置場所なんて毎回変わるもんだと思ってたけど。
47デフォルトの名無しさん:2009/02/08(日) 09:56:23
毎回辞書引きすればいいだろ。
481:2009/02/08(日) 12:07:53
>>21の方法で関数名調べて検索するんですね。
でも>>21の関数がなんか使い方わかりにくくて
49デフォルトの名無しさん:2009/02/08(日) 16:14:48
VC++ 使ってても、今時 MFC なんて使わない。
map ファイルはリンクの度に作成される。

ON_COMMAND マクロを書き換えて、適当なロギング処理呼び出しを加えなさい。
直接書き換えるのが嫌なら、ON_COMMAND を呼ぶ自作マクロを作ってそれに置き換えなさい。

そしたら削除依頼を出してきなさい。

一体どうしたら、こんなに無知無能且つ傲慢になれるのだろう。
50デフォルトの名無しさん:2009/02/08(日) 17:43:03
>>49
なんで莫迦な>>1の相手すんだお前は。
>そしたら削除依頼を出してきなさい。
莫迦な>>1なんだからそんな殊勝な事するワケないだろ。
511:2009/02/11(水) 07:36:28
>>49
MFC使わないってマジで?むしろ使ってないほうが遅れすぎてる、の間違いじゃねーの?
自作マクロとかそんなんアリ?考えたこともねーよ。
52デフォルトの名無しさん:2009/02/11(水) 07:49:26
ちんちん
53デフォルトの名無しさん:2009/02/12(木) 04:28:30
良スレあげ
54デフォルトの名無しさん:2009/03/18(水) 20:12:07
はいはい
55デフォルトの名無しさん:2009/03/25(水) 23:28:48
誰か2次元配列のポインタ渡しを教えて下さい。
void fun(char *a[]){
int i;
for(i=1;i<=10;i++){
a[i]="test";}}

void main(void){
char cr[10][100];
int i;
fun(cr);
for(i=0;i<=10;i++){
printf("test->%s\n",cr[i]);
}}
上記の様なことをしたいのですが、どの様に訂正したら問題なく動くのでしょうか?
56デフォルトの名無しさん:2009/03/26(木) 12:40:36
>>55
「の様なこと」がさっぱりわからん。
2次元配列のポインタを受け取る関数の宣言なら
void fun(char (*a)[10][100])
57デフォルトの名無しさん:2009/03/27(金) 08:14:35
void fun(char *a[]){ ×

void fun(char (*a)[]){ ○
58デフォルトの名無しさん:2009/03/27(金) 08:15:33
添え字わすれてた

C99ならこれでいけないだろうか、試してないしうろ覚えだけど
void fun(char (*a)[*]){
59デフォルトの名無しさん:2009/03/27(金) 09:41:33
>>55
void fun(char *a[]){

void fun(char a[][100]){
に、
a[i]="test";}}

memcpy( a[i], "test" );}}
に。

配列とポインタと文字列をまだキッチリと理解してない。
多くの人が難解に思うところだから頑張れ。
60デフォルトの名無しさん:2009/03/28(土) 00:09:07
memcpy()してどうするw
61デフォルトの名無しさん:2009/03/28(土) 00:10:51
つーか、楽しい関数名だな。
62デフォルトの名無しさん:2009/03/28(土) 00:13:32
簡単にクラッシュするプログラムを作れるのがC言語の醍醐味
6359:2009/03/28(土) 08:56:52
こっぱずかしw

>>62
コンパイルエラー(memcpy()の引数が足りない)なのでクラッシュはせずに済むようだorz
64デフォルトの名無しさん
openc++ 使えば?