トップページ⇒tech
1001コメント299KB

C#, C♯, C#相談室 Part42

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2007/08/26(日) 12:42:25
(#゚ー゚)つ < C#、.NETの話題はこちらでどうぞ。

前スレ
C#, C♯, C#相談室 Part41
http://pc11.2ch.net/test/read.cgi/tech/1184840053/

過去スレは>>2-5あたり。
0360デフォルトの名無しさん2007/09/05(水) 15:30:10
dt=$.split(' \n');dt[dt.length]='';for(i=0;undefined!=dt[i];i+=2){write(dt[i-i%2+1].replace('jp.','').replace('www.',''));br();write(dt[i-i%2]);br();}
0361デフォルトの名無しさん2007/09/05(水) 15:36:46
>>359
使うメンバだけラップすれば良いよ。
COM 化するって手もある。
03623592007/09/05(水) 15:53:00
>>361
なるほどCOMって手も。。

説明まちがえた。
すべてのメンバか使うメンバだけって、ところが問題じゃなく、
いちどC++/CLIでラップしなければいけないのかどうか、知りたかった。

ラップするのはここではC++/CLIだが、
直接C#でラッパを書いて、マネージドのクラスライブラリを作ることは
可能ですか?
0363デフォルトの名無しさん2007/09/05(水) 16:01:12
>>362
C++/CLI でラッパを書く、C++ で COM 化するのいずれも避けるには?ってことですか。

ヘッダファイルとオブジェクトファイル(あるいはソースコード)で供給されるような普通の
良くあるクラスライブラリの場合、そもそもライブラリ側のコードを呼び出す手段が無い
ですよね。

dllexport されているクラスなら MSVC の ABI に従って呼び出してあげれば動くでしょうけど、
そういうライブラリはあまりないし、割に合わないような気がする。
0364デフォルトの名無しさん2007/09/05(水) 16:34:36
今ハードウェアとやりとりをしなければならないので、PInvoke を使って DLL にアクセスしています。
この DLL の Open 関数を構造体を引数として呼んであげると、この構造体の中にデータが入って
返ってくるというものです。
で問題はこの構造体のメンバに構造体の配列が入っており、この構造体の配列を取得することが
できません。( 構造体の他の int のメンバは取得できています。以下でいうところの ID )
このような構造体下の構造体を取得することはできないのでしょうか。

struct Parent
{
public int ID;
public Data[];
}

struct Data
{
public int RawData;
public int Length;
}
03653592007/09/05(水) 16:38:33
>>363
すみません、最後の、
dllexport されているクラスなら(snip)動くでしょうけど、
について、もすこし教えてください。dllexportすれば、
C#から直接呼べますか?
0366デフォルトの名無しさん2007/09/05(水) 16:59:15
>>365
exportする側は
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:01
あなたがCでDLLExportされたC++クラスのコンストラクタを起動し、
vtblに格納されているか少なくとも名前マングリングされたthisコールの
メンバ関数を起動し、スローされた例外を上手いこと取り扱い、最後に
デストラクタを起動して破棄できるのなら、C#でもきっと出来るだろう。
0368デフォルトの名無しさん2007/09/05(水) 18:36:48
大人しくEXEキックしてコンソールで取り込めば?
03693592007/09/05(水) 19:13:34
>>366 367 368
みなさん。ありがとうなんとなく理解した。

[DllImport("native.dll")] extern static void Hoge()で、
C#から、Cの関数は呼べる仕組みがあるし(マーシャリングもあるし)、
マネージドであるC++/CLIからは、C++/Native のオブジェクトをnewできるし、
なので、C#からC++/Nativeにアクセスできる方法も実はあるんじゃないかと、
ちょっと期待して質問してました。
0370デフォルトの名無しさん2007/09/05(水) 21:11:06
>369
これはマジレス
キャストやアンマネージDLLを使うならVB.NETがいい。

VBFixedArrayにDECLAREで処理するDLLをC#で呼ぶ。
アンマネージVBが噛むと処理が激重だから、処理が軽いもの限定だけど。

FORTRAN
C
C++
で構造体処理するDLLも一発でいくよ
0371デフォルトの名無しさん2007/09/05(水) 21:12:58
VB 使うくらいなら俺は C++/CLI を選ぶぜ
0372デフォルトの名無しさん2007/09/05(水) 21:29:01
エクセルとか操るならVBの方がずっと楽だと思うけど、
アンマネージdllの関数呼ぶ手間はあんまり変わらないんじゃない?
0373デフォルトの名無しさん2007/09/05(水) 21:32:03
>371
C++/CLIでやるのもありだな。2003ですまない
0374デフォルトの名無しさん2007/09/05(水) 21:34:15
>372
それはVB.NETじゃなくないか?
03753592007/09/05(水) 21:38:27
>>370
ラッパをVBで書く?
>>371
私もなんとなく同意。

やりたいことは、ネイティブなC++クラスライブラリを、
マネージド(C#)から使えるクラスライブラリにしたい。です。

結局C++/CLIでくるむ方法を取ることになりそうで検討中ですが、、
publicなクラス → ラッパクラス
interface → ??
publicなメンバ関数 → 全部ラッパ
publicなメンバ変数 → プロパティ
#define定数 → static const な定数
struct → ??
enum → ??

どのように書き換えたらいいか、わからないとこ満載だ。
どなたか、??のところを教えてください。

0376デフォルトの名無しさん2007/09/05(水) 21:41:15
バイナリーを読む場合ポインタTOストラクチャを使うC#に対してVBは一発で入るよ?

同じかな?
0377デフォルトの名無しさん2007/09/05(水) 21:43:47
>375
それなら2005を買ってみな。
ヘッダ読めばそのまま動く
0378デフォルトの名無しさん2007/09/05(水) 21:48:34
すまない、ちょっと言葉が足りなかった
使いたいライブラリをC++でインクルード

コンパイル

C#で参照設定
.NETプロジェクト

これで全部使える
0379デフォルトの名無しさん2007/09/05(水) 21:52:49
VB.NETでラッピングする場合は、DECLAREで定義。引数は全てVARIANTのFIXEDARRAY
(OBJECTだと通らないから注意)
で、きちんとした型をCTYPEで渡せば動作する

楽じゃないか?
0380デフォルトの名無しさん2007/09/05(水) 21:56:22
>>375
>マネージドであるC++/CLIからは、C++/Native のオブジェクトをnewできるし、

ネイティブのライブラリは実はCのランタイムライブラリが裏で色々サポートしているので
newの部分だけ見てても混乱するよ。

内部でCRTヒープ使ってるかもしれないし、
atexitみたいなコールバックに依存しているかもしれない。

一般論として、Cのライブラリは静的リンクなり動的リンクなりのCRTを必要とする。
そのCRTとの連携無しに、C#から
直接Cのコード使おうってのはちょっと無謀じゃないかな。

相手がDLLの場合、LoadLibraryされたときに自分でCRTの初期化やるから
その辺気にする必要はないんだけど。
0381デフォルトの名無しさん2007/09/05(水) 23:44:08
んん? そのためのC++/CLIなんだから、CRTのルールを守らず
アセンブリをロードするとは思えんけど。

http://msdn2.microsoft.com/ja-jp/library/ms173266(VS.80).aspx
0382デフォルトの名無しさん2007/09/05(水) 23:50:54
>>381
C++/CLIはそれでOK。そこは同意。

よく分からないのは359が言うところのクラスライブラリが
どんなファイル形式なのかかな?

1) *.h 単体 (テンプレートライブラリ)
2) *.h+*.lib
3) *.h+*.obj
4) *.h+*.dll
5) *.h+*.cpp

>>>359 は
>いちどC++/CLIでラップしなければいけないのかどうか、知りたかった。
とか書いている割に、どんな形態で配布されているライブラリなのか
未だに明かしていないみたいだけど。
03833592007/09/06(木) 01:46:34
>>382
わかりにくくてすんません。一番最初にあげた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はそのために存在している。ので、いまこそ使うときだ。
ってことですかね。
03843592007/09/06(木) 02:01:14
>>370 >>379
VB.NETはまったく未開の地だ。ちょっとみてみる。ありがとう。

>>377 >>378
ん。COMの話?
0385デフォルトの名無しさん2007/09/06(木) 11:42:05
どうもデリゲートの使いどころがわからないんですが
イベントのメソッドはわかるんですが
おーデリゲートってすげー!!!
っというような使用法ってどういうのですかね
0386デフォルトの名無しさん2007/09/06(木) 11:48:38
//List<int> list;
list.Sort(delegate(int x, int y){return y.CompareTo(x);});//逆順ソート
0387デフォルトの名無しさん2007/09/06(木) 12:18:08
>>385
そもそもイベントはdelegateのシンタックスシュガー似すぎな一ツーの
0388デフォルトの名無しさん2007/09/06(木) 12:40:05
>>386
それって匿名メソッドスゲーの例じゃないの。
0389デフォルトの名無しさん2007/09/06(木) 12:46:03
C#2.0になってジェネリックや暗黙のインスタンス作成や匿名メソッドが付いて
デリゲートが使いやすくなったけど、その前は単体ではあんまり積極的に使われなかったような
0390デフォルトの名無しさん2007/09/06(木) 13:00:11
イベントとか意味わかんねえ
+=と-=しかできないし
なんに使うんだよ
0391デフォルトの名無しさん2007/09/06(木) 13:01:53
>>390
イベントのハンドリングだとおもう。
0392デフォルトの名無しさん2007/09/06(木) 13:04:04
普通にdelegate使った方が入れ替えられて便利じゃん
無駄なフェイルセーフだぜ
0393デフォルトの名無しさん2007/09/06(木) 13:08:04
一応プロパティと同じように実装の変更もできる
0394デフォルトの名無しさん2007/09/06(木) 13:08:20
>>390
IDEによるポトペタ
03953852007/09/06(木) 13:17:22
>>386>>388
そうですね匿名メソッドですね
>>387
そうですか…なんかイベントの話になってきてますね
んーデリゲートでこんな風にしたらすっごい便利!
とかいう話ないですかね
0396デフォルトの名無しさん2007/09/06(木) 13:45:38
void Hoge() { list.ForEach(Print); }
void Print(int x){ Console.WriteLine(x); }
コレクション関係以外にないかなあ
0397デフォルトの名無しさん2007/09/06(木) 13:58:02
>>395 処理のインジェクションしたいところにはdelegateばんばん使ってます。
クラスの生成時とかにそのシチュエーションに併せて動作を変えたいとき便利。
0398デフォルトの名無しさん2007/09/06(木) 14:00:41
インターフェースを実装したクラスを作るよりも楽>delegate
0399デフォルトの名無しさん2007/09/06(木) 14:55:19
Action<T>は

interface 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
interfaceでは大げさすぎる場合も多いし、例えばイベントハンドラを
インタフェースとして実装した場合、同じWidgetを複数個持とうとするとに
インタフェースが衝突する、といった問題が生じる。Javaではこれを解決
するのに一々ゴテゴテと無名クラスを記述する羽目になり、実に馬鹿馬鹿しい限りだ。

ラムダ式が無くとも、delegateであれば上記の問題は普通に解決することが
出来る。

まあ、処理を汎用化したり(例えば描画ルーチンに、PixelをPutする
ルーチンだけdelegateとして与えられるようにすれば、汎用になる)、
テーブルジャンプっぽく使ったり(メニュー等のindexとdelegateの配列を
結びつけたりする)、意思決定と実行のタイミングが分かれている場合に、
意思決定→delegate変数に保存→delegateを用いて実行といったことをやったり
(実行が何度も行われる際に、無駄な条件分岐を完全に取り除くことが出来る)、
色々と応用範囲は多い。
0401デフォルトの名無しさん2007/09/06(木) 15:17:17
delegate使うとエディットコンティニューでやり直しになるのがデメリット
0402デフォルトの名無しさん2007/09/06(木) 17:37:05
久々にThreadPool.GetMaxThreads()を実行してみたらワーカースレッドが500、I/Oスレッドが1000になってた。
前はもっと少なかった気がするんだけど・・・なぜでしょうか?
04033852007/09/06(木) 19:32:29
なるほどーみなさんいろいろ使ってますね
デリゲート道、精進します
ありがとうございました
0404デフォルトの名無しさん2007/09/06(木) 20:04:16
>402
前は少なすぎたせいでスレッドプールが一杯になって例外が起きるケースがあったのでので.NET2.0から事実上無制限といえる値に増やされた。
なにげに呼んだクラスが内部でスレッドプールを使っててスレッドプールの上限で例外吐かれたりしても対処しようがないじゃん。
0405デフォルトの名無しさん2007/09/06(木) 20:10:45
ClassAのイベントにメソッドを紐付けしてるClassBがシリアル化可能じゃないと
ClassAまでシリアル化できなくなっちゃうけど、これって何か回避方法ないかな?

あと、デリゲートにインスタンスメソッド登録するということは、
デリゲートに参照を持たれる(つまりGCが働かない)こととやっぱり等価になるの?
0406デフォルトの名無しさん2007/09/06(木) 20:20:37
当たり前
っていうかイベント結びつけたままシリアライズしたいって
いったいどんなときなの?
0407デフォルトの名無しさん2007/09/06(木) 20:22:28
ああひょっとしてシリアライズさせない方法が分からないってことか?
メンバにつける属性で制御できるよ
0408デフォルトの名無しさん2007/09/06(木) 20:43:28
でもNonSerializedAttributeってイベントには付けられないと思うんですが。。
0409デフォルトの名無しさん2007/09/06(木) 20:56:27
>>405
デリゲートを明示的に宣言してそのデリゲートにNonSerializedつければいいらしい。
↓参照
http://www.thescripts.com/forum/thread245864.html
04104092007/09/06(木) 21:01:10
[field: NonSerialized]でもできるみたいだな
こっちのほうがスマートか。
0411デフォルトの名無しさん2007/09/06(木) 21:09:45
>>409-410
ありがと。
しかし、そんなマンマの回答よく短時間に見つけられるもんだね関心しちゃうよ
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
>>413

そのクラスの人間なんて見たときねーよ
0416デフォルトの名無しさん2007/09/06(木) 22:02:47
すみません。どれが自作自演でしょうか?
0417デフォルトの名無しさん2007/09/06(木) 22:03:48
やまだだけどなんでもそうだんにのるよ!!
0418デフォルトの名無しさん2007/09/06(木) 22:05:47
>>414
jが必要になったらどうする。
0419デフォルトの名無しさん2007/09/06(木) 22:06:12
やまだくんはネームスペースをだな
0420デフォルトの名無しさん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
>416
じえんはないけどえいえんはあるよ!
0422デフォルトの名無しさん2007/09/06(木) 22:12:35
たなかさんめそっどめいのせんすないからきらいだ!

そうだ。こういうときは・・・おーばーろーどがあるじゃないか!

やまだはそっとたなかのめそっど名のぷれふぃっくすに
OVERROAD_
をつけたした。
これでなまえがかぶることはない。
0423デフォルトの名無しさん2007/09/06(木) 22:15:09
スレが壊れだした
0424デフォルトの名無しさん2007/09/06(木) 22:15:21
>418
よくじつにまわすか、ぷれふぃっくすにSTATIC_とかつければかいけつだよ(^^)
0425デフォルトの名無しさん2007/09/06(木) 22:17:18
>423
すまない。ガチでこんなコードの修正依頼にイラついて書いてしまった。
後悔はしていない
0426デフォルトの名無しさん2007/09/06(木) 22:19:11
マでやれ
0427デフォルトの名無しさん2007/09/06(木) 22:22:43
for(LOOPCOUNTER_[LOOPCOUNTER_1,LOOPCOUNTER_2]=58;END==TRUE;LOOPCOUNTER_1**)
{
}

やまだすごくね?
0428デフォルトの名無しさん2007/09/06(木) 22:23:33
名前空間の無い言語はきついな
0429デフォルトの名無しさん2007/09/06(木) 22:24:51
END==TRUEってなんぞ
0430デフォルトの名無しさん2007/09/06(木) 22:25:40
>>428
どちらかというとセンスのないプロ…
0431デフォルトの名無しさん2007/09/06(木) 22:33:45
ちなみに言語はC#だぜW
0432デフォルトの名無しさん2007/09/06(木) 22:35:04
ENDがTRUEの間ループをまわすの?
普通に発狂するわ
0433デフォルトの名無しさん2007/09/06(木) 22:39:10
もっとやまだのコードがみたい
0434デフォルトの名無しさん2007/09/06(木) 22:39:56
ディフォルトTRUE
スイッチFALSEとコメントある。
わからない事もない
0435デフォルトの名無しさん2007/09/06(木) 22:44:32
ディフォルトって何?
0436デフォルトの名無しさん2007/09/06(木) 22:45:54
マでやれ
0437デフォルトの名無しさん2007/09/06(木) 22:48:14
やまだソース今度ZIPであげるわ
0438デフォルトの名無しさん2007/09/06(木) 22:48:38
なんで大文字なんだろ
0439デフォルトの名無しさん2007/09/06(木) 22:49:42
小文字だと予約語などにぶち当たるからだろ。
それかOLD BASICの名残。
0440デフォルトの名無しさん2007/09/06(木) 23:08:58
まだLOOP==TRUEの方が理解できる
0441デフォルトの名無しさん2007/09/06(木) 23:56:29
ブレークポイント設定してもデバッグができなくなる現象が突然でました。
どの辺確認すればいいのでしょう?構成はDebugでやってますが
0442デフォルトの名無しさん2007/09/07(金) 00:01:03
ブレークポイントまでいってない説
0443デフォルトの名無しさん2007/09/07(金) 00:08:40
リビルドすれば治る説
0444デフォルトの名無しさん2007/09/07(金) 00:10:56
ブレークポイントはForm_Load内なので、到達してるんです。
性格にはブレークポイントに到達して、デバッグモードになるのに凄い時間がかかって
デバッグモード後はF10で1ステップ進ませると、デバッグモード解除されてしまいます
0445デフォルトの名無しさん2007/09/07(金) 00:21:14
Form_Loadのブレークポイントの後に続く文があるのに
デバッグモード解除されるんだったら、
多分VSがぶっ壊れてるんだと思うよ
再インスコじゃね
0446デフォルトの名無しさん2007/09/07(金) 00:31:52
不思議なことに、あるプロジェクトでしか現象出ないんだけど、
とりあえず朝一で再インストールしてみます
0447デフォルトの名無しさん2007/09/07(金) 00:37:35
>444
デバッグのオプションのネイティブのチェックを外して.NETのみをデバッグするようにしたらどうなる?
0448デフォルトの名無しさん2007/09/07(金) 00:40:18
>>447
すんません。ソースが会社なんで、明日やってみます。thx
0449デフォルトの名無しさん2007/09/07(金) 01:27:48
「〜〜〜は開始されませんでした」みたいなエラーメッセージがでて
デバッグ開始が異常に遅くなるときあるよね。
0450デフォルトの名無しさん2007/09/07(金) 13:13:13
>>378
kwsk
0451デフォルトの名無しさん2007/09/07(金) 15:01:14
ソリューションのクリーンとか試してみた?
0452デフォルトの名無しさん2007/09/07(金) 16:39:10
怪しいアプリに邪魔されてた事とかあるな
0453デフォルトの名無しさん2007/09/07(金) 19:05:00
質問です。

TextBoxコントロールの枠線の色は変更できますか?
できそうにない感じなのですが、そうすると自分で線を描くしかないかと
思うのですが、

Graphics g = this.CreateGraphics();

と取得してコレに対してDrawLineをしてみているのですが、
線が表示されません。

アプローチが間違っているのか、足りないおまじないがあるのか…。

どなたかお知恵をお貸しいただければ幸いです。
0454デフォルトの名無しさん2007/09/07(金) 19:49:42
>453
まずその描画はOnPaintでやるべき。

なんとなく、Panelとかの上にTextBoxを載っけてPanelとかに枠線描いた方が楽じゃない?
0455デフォルトの名無しさん2007/09/07(金) 19:59:40
>>453
いわゆるオーナードローっぽいことがやりたいのならControlPaintを使うようだから
詳細はMSDNを見るといい

が、>>454に同意だな
0456デフォルトの名無しさん2007/09/07(金) 20:19:15
>>454
> まずその描画はOnPaintでやるべき。
TextBoxBase 以下は OnPaint が無視されたような気がする。
0457デフォルトの名無しさん2007/09/07(金) 20:52:07
>450
2003までのCPPはマネージとアンマネージはクラス分けされ、同一コード内にはかけても、そこからメモリへの受け渡しが辛かった。
2005はマネージとアンマネージを並べてかける。
つまり

int A=42
printf(A.Tostring());
みたいな事ができる。
0458デフォルトの名無しさん2007/09/07(金) 20:56:41
何かしょぼいが解る人にはマジで!と叫ぶようなコード。
0459デフォルトの名無しさん2007/09/07(金) 21:15:38
>>453
やってみると意外と面倒だね。

枠の幅が1でよければ、BorderStyle =BorderStyle.FixedSingleにしておいて
WM_PAINT捕まえてそこで枠を描画すればできる。
■ このスレッドは過去ログ倉庫に格納されています