C#, C♯, C#相談室 Part42
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2007/08/26(日) 12:42:25前スレ
C#, C♯, C#相談室 Part41
http://pc11.2ch.net/test/read.cgi/tech/1184840053/
過去スレは>>2-5あたり。
0322デフォルトの名無しさん
2007/09/04(火) 21:35:51MSDNも普通にフリーとして公開されてなかったか?
0323デフォルトの名無しさん
2007/09/04(火) 21:54:39C:\windows\Microsoft.NET\framework\以下にあるのでそんな気がしますが。
0324デフォルトの名無しさん
2007/09/04(火) 21:57:130325デフォルトの名無しさん
2007/09/04(火) 22:03:35おお、そうだったんですか。
これで安心してCodeDomが使えます。
0326デフォルトの名無しさん
2007/09/04(火) 22:17:14標準なのにドマイナーなのがひとつ
0327デフォルトの名無しさん
2007/09/05(水) 00:09:57ループの中から呼んだりして大丈夫なんだろうか。
何千何万って呼んだらなんか嫌なことになりそうな気がする。
0328デフォルトの名無しさん
2007/09/05(水) 00:15:47説明調の、他人に意味がちゃんと通じる文章書けよ
0329デフォルトの名無しさん
2007/09/05(水) 00:23:22それは説明するまでもないと思ったけど。
何が通じてないのかわからん。
Invoke系のメソッドってのはInvoke、BeginInvokeのことだよ
それらを呼んだら内部的に生成されるオブジェクトでファイナライザが呼ばれるっぽいんで嫌だなって話。
0330デフォルトの名無しさん
2007/09/05(水) 00:37:100331デフォルトの名無しさん
2007/09/05(水) 00:38:28読む側の立場に立って自分の文章推敲できない人間はたいていそうだ。
ついでに、ファイナライザのコスト?
意味がわからない。
デリゲートを処分するコストがそんなかかるのかね?
仮にかかるとして、コストとは「時間当たりのCPUの使用量」のことだと思うが、
どのみちmsのオーダーでInvokeとか不可能だから意味がないだろう。
0332デフォルトの名無しさん
2007/09/05(水) 00:39:31いったいどんな頻度でControl.Invokeなんかを実行する気だ?
0333デフォルトの名無しさん
2007/09/05(水) 00:44:23再描画を伴わないControl.Invokeの使い道って
あんまり思いつかないんだけどどうだろ?
経験上、何千何万って単位でControl.Invokeを呼ぶと
再描画コストが恐ろしいことになる。
WinFormsなら1秒間に10回ぐらいの更新でいいんじゃないかね?
まあそれ言い出すとTimerでいいじゃんて話も多いんだけど。
0334デフォルトの名無しさん
2007/09/05(水) 00:44:31CLR Profilerで見れるよ。
>>331
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpdndotnet/htm/dotnetgcbasics.asp
この辺でも読んでくれ。
なんでデリゲートが出てくるのかわからんが・・・
>>332
別スレッドでなんかの処理中にUIを更新するために呼んだりしない?
まあ何万は言いすぎかも。
0335デフォルトの名無しさん
2007/09/05(水) 01:04:23ヘルプから見れるキーワードとか目次がMSDNなんですか?
0336デフォルトの名無しさん
2007/09/05(水) 01:05:13読んでくれって、どこにもお前さんが主張しているような類のことは書いてないだろw
0337デフォルトの名無しさん
2007/09/05(水) 01:10:27Control.Invokeを使ったらファイナライザが実行されたってこと?EndInvokeしてても?
0338デフォルトの名無しさん
2007/09/05(水) 01:13:32Control.Invokeで実行されるというファイナライザを持つオブジェクトが内包するオブジェクトとか。
Control.Invokeを実行する通常の頻度とかから考えて、それが問題になるほどコストが高いとは思えん
ということだよ。
「ファイナライザのコストが高い」という表現自体をそのまま疑ってるんじゃない。
ついでにEndInvokeしたらファイナライザは実行されないんじゃないの?普通に考えて。
と思っただけで、まあこれはプロファイラで確認してそうなってるってんならそうなのかもしれん。
0339デフォルトの名無しさん
2007/09/05(水) 01:17:46VS2005 Expressのヘルプに標準で何が入っているかは知らないが、MSDNライブラリはこれ。
ttp://www.microsoft.com/downloads/details.aspx?FamilyID=b8704100-0127-4d88-9b5d-896b9b388313&DisplayLang=ja
2.5Gバイトほどあるから注意してくれ。
0340デフォルトの名無しさん
2007/09/05(水) 01:22:22GCを二回行わなければならず単純計算でGCにかかる時間が倍になるんじゃなかったか
0341デフォルトの名無しさん
2007/09/05(水) 01:27:36>>338
EndInvokeしても呼ばれるみたい。
やっぱgen0でちゃちゃっと回収されるから問題が少ないってことなのかな?
具体的にはControl.ThreadMethodEntryってオブジェクトだけど
ファイナライザの処理自体はシンプルだけど他のオブジェクトへの参照は割とごっそり保持してるみたいだな。
まあ他に代替手段があるわけじゃなしどうこういっても仕方ないんだけどね。
0342デフォルトの名無しさん
2007/09/05(水) 01:42:58いらねーじゃねーかよ。
0343デフォルトの名無しさん
2007/09/05(水) 01:48:44そんなに困らないオブジェクトが多いけどな。
まあ引数とか戻り値はクリアしてほしいところだが
0344デフォルトの名無しさん
2007/09/05(水) 01:58:26GUIアプリだし、特にControl.Invokeなんて同期実行なんだから、まあ普通はまずGEN1ですべて回収できるだろう。
0345デフォルトの名無しさん
2007/09/05(水) 02:05:060346319
2007/09/05(水) 11:20:12一応、下記ソースに変更出来ました。
的確な助言、ありがとうございました。
if ((string)(Session["Body"]) == null)
{
Label1.Text = "<br />";
} else {
Label1.Text = ((string)(Session["Body"])).Replace("\r\n", "<br />");
}
0347デフォルトの名無しさん
2007/09/05(水) 11:24:430348319
2007/09/05(水) 11:45:52ご助言の通り、as演算子をしらべました。
お陰でたまに出るエラーがなくなりました。
さすがは神ですね。
即レスにも関わらず、100%的中でした。
なぜ、私がたまに出る意味が理解できないエラーで苦労している所を
お察し出来たのか愚民にはわかりませんが、
貴方の英知で、救われました。
再びお礼を申し上げます。
string s = (string)(Session["Body"]) as string;
if (s == null)
{
Label1.Text = "<br />";
} else {
Label1.Text = ((string)(Session["Body"])).Replace("\r\n", "<br />");
}
0349319
2007/09/05(水) 12:08:38string s = (string)(Session["Body"]) as string;
if (s == null)
{
LabelBody.Text = "<br />";
} else {
LabelBody.Text = s.Replace("\r\n", "<br />") + "<br />";
}
0350デフォルトの名無しさん
2007/09/05(水) 12:18:23string s = Session["Body"] as string;
じゃないとエラーでるっしょ
0352デフォルトの名無しさん
2007/09/05(水) 12:39:14エラーは出ないけど
string m = ((string)"Hello")
とはやらないだろって事じゃない?
0353デフォルトの名無しさん
2007/09/05(水) 12:59:04うん。私もそう思ったので、助言どおりに直しました。
だから、「助言ありがとう」とカキコしたよ。(^^
0354デフォルトの名無しさん
2007/09/05(水) 13:34:371. foreachのループの中でコレクションの書き換えをしたい。
2. foreachのループ変数を書き換えることによって、ループの制御をしたい
1.なら foreachのループ変数はコレクションの要素とは無関係な場合もある。
そもそも、IEnumerableには「要素」の概念はないし、arrayみたいにIListを実装した
インデックスを通じて要素にアクセスできるコレクションとは限らない。
2なら、ループのカウンタはIEnumerableの内部でループ変数とは別に
管理されているから、無駄(というか、おそらく何も起きない)。
だと思うんだけれど、ほかに何か書き込み許容するといいことってありますかね?
0355デフォルトの名無しさん
2007/09/05(水) 13:54:18ちゃんと読めとしか言いようがないが、1でも2でもない(つーか2は意味がわからんが)
あえて例を出すならこんなことがしたいんでしょ
foreach (string str in input)
{
str = str.Trim().ToLower();
if (str.Length == 0) throw new exception("Invalid");
Console.WriteLine(str);
}
0356デフォルトの名無しさん
2007/09/05(水) 14:15:34なるほど、そういうことか。全然議論が見えてなかった。
Console.WriteLine(str.Trim().ToLower());
でも書き込み禁止だとエラー出るのかな???
355さんの例みたいに条件分岐したいような場合は
たとえ書き込み禁止じゃなくても、可読性のために仮変数おいたほうが
いいとおもうけど…。
0357デフォルトの名無しさん
2007/09/05(水) 14:15:34object o = 1;
string s = (string)o as string;
0358デフォルトの名無しさん
2007/09/05(水) 14:29:43それはなんだ?
0359デフォルトの名無しさん
2007/09/05(水) 15:28:55ttp://www.atmarkit.co.jp/fdotnet/special/vcppinvista01/vcppinvista01_03.html
のように、publicメンバすべてをラップしか、方法ありませんか?
0360デフォルトの名無しさん
2007/09/05(水) 15:30:100361デフォルトの名無しさん
2007/09/05(水) 15:36:46使うメンバだけラップすれば良いよ。
COM 化するって手もある。
0362359
2007/09/05(水) 15:53:00なるほどCOMって手も。。
説明まちがえた。
すべてのメンバか使うメンバだけって、ところが問題じゃなく、
いちどC++/CLIでラップしなければいけないのかどうか、知りたかった。
ラップするのはここではC++/CLIだが、
直接C#でラッパを書いて、マネージドのクラスライブラリを作ることは
可能ですか?
0363デフォルトの名無しさん
2007/09/05(水) 16:01:12C++/CLI でラッパを書く、C++ で COM 化するのいずれも避けるには?ってことですか。
ヘッダファイルとオブジェクトファイル(あるいはソースコード)で供給されるような普通の
良くあるクラスライブラリの場合、そもそもライブラリ側のコードを呼び出す手段が無い
ですよね。
dllexport されているクラスなら MSVC の ABI に従って呼び出してあげれば動くでしょうけど、
そういうライブラリはあまりないし、割に合わないような気がする。
0364デフォルトの名無しさん
2007/09/05(水) 16:34:36この DLL の Open 関数を構造体を引数として呼んであげると、この構造体の中にデータが入って
返ってくるというものです。
で問題はこの構造体のメンバに構造体の配列が入っており、この構造体の配列を取得することが
できません。( 構造体の他の int のメンバは取得できています。以下でいうところの ID )
このような構造体下の構造体を取得することはできないのでしょうか。
struct Parent
{
public int ID;
public Data[];
}
struct Data
{
public int RawData;
public int Length;
}
0365359
2007/09/05(水) 16:38:33すみません、最後の、
dllexport されているクラスなら(snip)動くでしょうけど、
について、もすこし教えてください。dllexportすれば、
C#から直接呼べますか?
0366デフォルトの名無しさん
2007/09/05(水) 16:59:15exportする側は
http://msdn2.microsoft.com/ja-jp/library/a90k134d(VS.80).aspx
あたりを参照
メンバ関数がどういう名前でexportされるかはコンパイラ依存。
dll 生成時の出来る lib を見て自分で調べる。
仮想メンバ関数は vtbl 経由でアドレスを取得。
MSVC の 呼び出し規約は基本 __cdecl ですが this を ecx に入れて呼ばなきゃないので、
そこだけは C++ というかアセンブラの補助が必要ですね・・・
0367デフォルトの名無しさん
2007/09/05(水) 17:00:01vtblに格納されているか少なくとも名前マングリングされたthisコールの
メンバ関数を起動し、スローされた例外を上手いこと取り扱い、最後に
デストラクタを起動して破棄できるのなら、C#でもきっと出来るだろう。
0368デフォルトの名無しさん
2007/09/05(水) 18:36:480369359
2007/09/05(水) 19:13:34みなさん。ありがとうなんとなく理解した。
[DllImport("native.dll")] extern static void Hoge()で、
C#から、Cの関数は呼べる仕組みがあるし(マーシャリングもあるし)、
マネージドであるC++/CLIからは、C++/Native のオブジェクトをnewできるし、
なので、C#からC++/Nativeにアクセスできる方法も実はあるんじゃないかと、
ちょっと期待して質問してました。
0370デフォルトの名無しさん
2007/09/05(水) 21:11:06これはマジレス
キャストやアンマネージDLLを使うならVB.NETがいい。
VBFixedArrayにDECLAREで処理するDLLをC#で呼ぶ。
アンマネージVBが噛むと処理が激重だから、処理が軽いもの限定だけど。
FORTRAN
C
C++
で構造体処理するDLLも一発でいくよ
0371デフォルトの名無しさん
2007/09/05(水) 21:12:580372デフォルトの名無しさん
2007/09/05(水) 21:29:01アンマネージdllの関数呼ぶ手間はあんまり変わらないんじゃない?
0373デフォルトの名無しさん
2007/09/05(水) 21:32:03C++/CLIでやるのもありだな。2003ですまない
0374デフォルトの名無しさん
2007/09/05(水) 21:34:15それはVB.NETじゃなくないか?
0375359
2007/09/05(水) 21:38:27ラッパをVBで書く?
>>371
私もなんとなく同意。
やりたいことは、ネイティブなC++クラスライブラリを、
マネージド(C#)から使えるクラスライブラリにしたい。です。
結局C++/CLIでくるむ方法を取ることになりそうで検討中ですが、、
publicなクラス → ラッパクラス
interface → ??
publicなメンバ関数 → 全部ラッパ
publicなメンバ変数 → プロパティ
#define定数 → static const な定数
struct → ??
enum → ??
どのように書き換えたらいいか、わからないとこ満載だ。
どなたか、??のところを教えてください。
0376デフォルトの名無しさん
2007/09/05(水) 21:41:15同じかな?
0377デフォルトの名無しさん
2007/09/05(水) 21:43:47それなら2005を買ってみな。
ヘッダ読めばそのまま動く
0378デフォルトの名無しさん
2007/09/05(水) 21:48:34使いたいライブラリをC++でインクルード
コンパイル
C#で参照設定
.NETプロジェクト
これで全部使える
0379デフォルトの名無しさん
2007/09/05(水) 21:52:49(OBJECTだと通らないから注意)
で、きちんとした型をCTYPEで渡せば動作する
楽じゃないか?
0380デフォルトの名無しさん
2007/09/05(水) 21:56:22>マネージドであるC++/CLIからは、C++/Native のオブジェクトをnewできるし、
ネイティブのライブラリは実はCのランタイムライブラリが裏で色々サポートしているので
newの部分だけ見てても混乱するよ。
内部でCRTヒープ使ってるかもしれないし、
atexitみたいなコールバックに依存しているかもしれない。
一般論として、Cのライブラリは静的リンクなり動的リンクなりのCRTを必要とする。
そのCRTとの連携無しに、C#から
直接Cのコード使おうってのはちょっと無謀じゃないかな。
相手がDLLの場合、LoadLibraryされたときに自分でCRTの初期化やるから
その辺気にする必要はないんだけど。
0381デフォルトの名無しさん
2007/09/05(水) 23:44:08アセンブリをロードするとは思えんけど。
http://msdn2.microsoft.com/ja-jp/library/ms173266(VS.80).aspx
0382デフォルトの名無しさん
2007/09/05(水) 23:50:54C++/CLIはそれでOK。そこは同意。
よく分からないのは359が言うところのクラスライブラリが
どんなファイル形式なのかかな?
1) *.h 単体 (テンプレートライブラリ)
2) *.h+*.lib
3) *.h+*.obj
4) *.h+*.dll
5) *.h+*.cpp
>>>359 は
>いちどC++/CLIでラップしなければいけないのかどうか、知りたかった。
とか書いている割に、どんな形態で配布されているライブラリなのか
未だに明かしていないみたいだけど。
0383359
2007/09/06(木) 01:46:34わかりにくくてすんません。一番最初にあげたurlの記事の内容そのまんまで、
WIN32で書いてあるスタティックのライブラリ。
2) *.h+*.lib
ってことになります。
ttp://www.atmarkit.co.jp/fdotnet/special/vcppinvista01/vcppinvista01_03.html
で、このとおりやってみようと思ったのだが、
>>375
で書いたとおり、メンバ関数をラップするだけじゃ足りなくて、
その他もろもろ細かいところすべて書き換えなきゃならなくなって。。。
ホントにこれが普通の方法なのか?もっとエレガントな方法があるのでは。
と、思ったのでした。
ちなみに、すべてではないですが、
4) *.h+*.dll
の形にしたものもあります。
MFC,ATL,stlは使っていなく、CRTは使っているものとそうでないものが。
>>380 >>381
Nativeと.NET、両方が扱える言語は、C++/CLIだけで、
っていうか、C++/CLIはそのために存在している。ので、いまこそ使うときだ。
ってことですかね。
0385デフォルトの名無しさん
2007/09/06(木) 11:42:05イベントのメソッドはわかるんですが
おーデリゲートってすげー!!!
っというような使用法ってどういうのですかね
0386デフォルトの名無しさん
2007/09/06(木) 11:48:38list.Sort(delegate(int x, int y){return y.CompareTo(x);});//逆順ソート
0387デフォルトの名無しさん
2007/09/06(木) 12:18:08そもそもイベントはdelegateのシンタックスシュガー似すぎな一ツーの
0388デフォルトの名無しさん
2007/09/06(木) 12:40:05それって匿名メソッドスゲーの例じゃないの。
0389デフォルトの名無しさん
2007/09/06(木) 12:46:03デリゲートが使いやすくなったけど、その前は単体ではあんまり積極的に使われなかったような
0390デフォルトの名無しさん
2007/09/06(木) 13:00:11+=と-=しかできないし
なんに使うんだよ
0391デフォルトの名無しさん
2007/09/06(木) 13:01:53イベントのハンドリングだとおもう。
0392デフォルトの名無しさん
2007/09/06(木) 13:04:04無駄なフェイルセーフだぜ
0393デフォルトの名無しさん
2007/09/06(木) 13:08:040394デフォルトの名無しさん
2007/09/06(木) 13:08:20IDEによるポトペタ
0395385
2007/09/06(木) 13:17:22そうですね匿名メソッドですね
>>387
そうですか…なんかイベントの話になってきてますね
んーデリゲートでこんな風にしたらすっごい便利!
とかいう話ないですかね
0396デフォルトの名無しさん
2007/09/06(木) 13:45:38void Print(int x){ Console.WriteLine(x); }
コレクション関係以外にないかなあ
0397デフォルトの名無しさん
2007/09/06(木) 13:58:02クラスの生成時とかにそのシチュエーションに併せて動作を変えたいとき便利。
0398デフォルトの名無しさん
2007/09/06(木) 14:00:410399デフォルトの名無しさん
2007/09/06(木) 14:55:19interface IHoge<T>
{
void Method(T arg);
}
とだいたい同等で
class A
{
public Action<Foo> Action;
}
class A
{
public IHoge<Foo> Action;
}
これもだいたい同等
a.Action = delegate(Foo foo){
....
};
これと
class FooHoge : IHoge<Foo>{ ... }
a.Action = new FooHoge(...);
これも大体同等
匿名メソッドなら直接かけるから一々定義したクラスを読まなくてすむので見やすい
ラムダ式になるともっと便利になる
匿名メソッド使わなくても、引数さえ合えばどんなメソッドでもはまるから、
いちいちinterface実装したクラスを作らなくて済む分楽
でもやっぱり真価は匿名メソッドで出てくる
0400デフォルトの名無しさん
2007/09/06(木) 15:04:40インタフェースとして実装した場合、同じWidgetを複数個持とうとするとに
インタフェースが衝突する、といった問題が生じる。Javaではこれを解決
するのに一々ゴテゴテと無名クラスを記述する羽目になり、実に馬鹿馬鹿しい限りだ。
ラムダ式が無くとも、delegateであれば上記の問題は普通に解決することが
出来る。
まあ、処理を汎用化したり(例えば描画ルーチンに、PixelをPutする
ルーチンだけdelegateとして与えられるようにすれば、汎用になる)、
テーブルジャンプっぽく使ったり(メニュー等のindexとdelegateの配列を
結びつけたりする)、意思決定と実行のタイミングが分かれている場合に、
意思決定→delegate変数に保存→delegateを用いて実行といったことをやったり
(実行が何度も行われる際に、無駄な条件分岐を完全に取り除くことが出来る)、
色々と応用範囲は多い。
0401デフォルトの名無しさん
2007/09/06(木) 15:17:170402デフォルトの名無しさん
2007/09/06(木) 17:37:05前はもっと少なかった気がするんだけど・・・なぜでしょうか?
0403385
2007/09/06(木) 19:32:29デリゲート道、精進します
ありがとうございました
0404デフォルトの名無しさん
2007/09/06(木) 20:04:16前は少なすぎたせいでスレッドプールが一杯になって例外が起きるケースがあったのでので.NET2.0から事実上無制限といえる値に増やされた。
なにげに呼んだクラスが内部でスレッドプールを使っててスレッドプールの上限で例外吐かれたりしても対処しようがないじゃん。
0405デフォルトの名無しさん
2007/09/06(木) 20:10:45ClassAまでシリアル化できなくなっちゃうけど、これって何か回避方法ないかな?
あと、デリゲートにインスタンスメソッド登録するということは、
デリゲートに参照を持たれる(つまりGCが働かない)こととやっぱり等価になるの?
0406デフォルトの名無しさん
2007/09/06(木) 20:20:37っていうかイベント結びつけたままシリアライズしたいって
いったいどんなときなの?
0407デフォルトの名無しさん
2007/09/06(木) 20:22:28メンバにつける属性で制御できるよ
0408デフォルトの名無しさん
2007/09/06(木) 20:43:280409デフォルトの名無しさん
2007/09/06(木) 20:56:27デリゲートを明示的に宣言してそのデリゲートにNonSerializedつければいいらしい。
↓参照
http://www.thescripts.com/forum/thread245864.html
0410409
2007/09/06(木) 21:01:10こっちのほうがスマートか。
0411デフォルトの名無しさん
2007/09/06(木) 21:09:45ありがと。
しかし、そんなマンマの回答よく短時間に見つけられるもんだね関心しちゃうよ
0412デフォルトの名無しさん
2007/09/06(木) 21:44:51すみません師匠にほしいです。
0413デフォルトの名無しさん
2007/09/06(木) 21:56:13どんな立場の人なのかきになるわ。マイクロソフト直々のサポート部隊が
書き込んでいるんじゃないかと思ってしまうくらいだ。
0414デフォルトの名無しさん
2007/09/06(木) 21:59:52きょうもすごいぷろぐらむをつくる。
int i = new int()
あれ、なにかへんだぞ。
intはたしか・・・
Int16
やまだくんはまだ満足しない。
iというなまえはかぶるかもしれないからあんぜんじゃない!
Int16 _USER_OBJECT_YAMADA_WRITE_200709062156_FOR_COUNTER
完璧なソースコードの誕生だ!
0415デフォルトの名無しさん
2007/09/06(木) 22:02:31そのクラスの人間なんて見たときねーよ
0416デフォルトの名無しさん
2007/09/06(木) 22:02:470417デフォルトの名無しさん
2007/09/06(木) 22:03:480418デフォルトの名無しさん
2007/09/06(木) 22:05:47jが必要になったらどうする。
0419デフォルトの名無しさん
2007/09/06(木) 22:06:120420デフォルトの名無しさん
2007/09/06(木) 22:06:28今日も嫌がらせを部下達にして楽しむ。
「iというなまえはかぶるかもしれないからあんぜんじゃない!
「Int16 _USER_OBJECT_YAMADA_WRITE_200709062156_FOR_COUNTER
「完璧なソースコードの誕生だ!
あれ、山田が何か楽しそうだぞ。
イヂワルしてやれ!
「山田君、このメソッドの名前は[_USER_OBJECT_YAMADA_WRITE_200709062156_FOR_COUNTER]にしてくれ
会議で決まったのだ!
0421デフォルトの名無しさん
2007/09/06(木) 22:06:31じえんはないけどえいえんはあるよ!
■ このスレッドは過去ログ倉庫に格納されています