C++/CLI part3at TECH
C++/CLI part3 - 暇つぶし2ch643:デフォルトの名無しさん
09/07/18 00:17:49
>>641
でもその場所はどうせデストラクタ・ファイナライザの内部以外に有り得ないでしょ。
それくらいだったらいいと思うけど。

でも、C++/CLIならauto_handleをクラスメンバにできなかったっけ?

644:デフォルトの名無しさん
09/07/18 00:23:20
でも、単独での呼び出しを書くことがあるというのは事実だよねって話

>>643
そいやC++/CLIってメンバに^付きで書かなきゃメンバのDisposeも勝手に読んでくれるんだよね

645:デフォルトの名無しさん
09/07/18 00:24:29
ファイナライザでDisposeは絶対ダメ
ファイナライザでメンバのマネージオブジェクトにアクセスするのは原則禁止

646:デフォルトの名無しさん
09/07/18 00:29:22
誤解を招くなぁそれ。C++/CLIのファイナライザ構文なんて
勝手にDispose呼び出しを生成してんぞ。

引数付きのDisposeパターンを守れってだけでしょ。

647:645
09/07/18 00:36:47
すまん言葉足らずだった
ファイナライザで"メンバの"Disposeはダメ

648:634
09/07/18 11:29:44
thx
こんなに沢山の人がいたんだ。。。

だいぶ慣れたと思ってたけど、まだわかってないことが多いみたい。
もっとお勉強するよ。
今回のは >>638 の auto_gcroot を使ってみようと思う。

>>637
C++ が好きなんだもん。w

649:デフォルトの名無しさん
09/07/18 15:01:37
auto_handleはマネージクラス・マネージコード内、
auto_gcrootはネイティブクラス・ネイティブコード内で使う。

650:デフォルトの名無しさん
09/07/18 15:51:27
C++好きなのはいいけど.NETに慣れる意味でも一度はC#やってみたほうがいいよ
なぜ本スレでさえアンマネージコードとの相互運用という本来の目的以外での
C++/CLIの使用に否定的な人が多いのか理解できるはず

651:デフォルトの名無しさん
09/07/18 15:57:56
相互運用ならC++/CLIはいい。もうC#でDllImportする気が起こらない。

652:デフォルトの名無しさん
09/07/19 00:02:11
URLリンク(clrinterop.codeplex.com)

653:デフォルトの名無しさん
09/07/19 00:13:08
いや、DllImportさえ簡単に貼り付けられればC#で問題ない、という程度のことではないから。

654:634
09/07/19 00:54:11
>>649
thx
勘違いして入れ替わってたよ。

auto_gcroot は変数定義した後に代入できるけど、auto_handle は変数定義の時の
初期化でしか代入できないとか、多分、何かの都合があるんだろうけど、面白いね。

>>650
どっちでも一応書ける。
だいたい画面系に C# 、それから呼ぶライブラリ関連に C++/CLI を。(最初にそうお勧めされた)
いまいち「目的外での C++/CLI に否定的」ってのがよくわかってないんだけど。。。
感覚的にはわかるような気もするけど、言語として C# の方に抵抗を感じたりして。

655:デフォルトの名無しさん
09/07/21 12:12:27
>>650
やっぱ、CLIは無意味?

656:デフォルトの名無しさん
09/07/21 18:51:25
>>655
ブリッジ


657:デフォルトの名無しさん
09/07/21 18:56:51
ドトネトにブリッジする理由は???

658:デフォルトの名無しさん
09/07/21 21:47:10
.NET開発の補助として使うものであって、決して
「.NETが使える便利なC++」ではない

659:デフォルトの名無しさん
09/07/21 23:02:04
適材適所という言葉があってだな(ry

660:デフォルトの名無しさん
09/07/22 08:06:27
この天気、日食どころじゃねーな。

661:デフォルトの名無しさん
09/07/22 09:19:19
それ食えるのか?

662:デフォルトの名無しさん
09/07/22 10:12:57
ドトネト材の適所って何?

663:デフォルトの名無しさん
09/07/22 10:35:54
Java+JNIと比べるとはるかに優れているな。
だれか、javaVM用のC++/CLI?を作ってくれ。

664:デフォルトの名無しさん
09/07/22 10:41:19
ハンドルの指すアドレスの最初の4バイトは何のデータですか?
昔.NETを勉強したときに、
オブジェクトヘッダーは同期ブロックインデックスと
クラス定義へのポインタで構成されてると
読んだ記憶があるんですが

665:デフォルトの名無しさん
09/07/22 12:55:00
>>664
知ってどうするんだよ?


666:デフォルトの名無しさん
09/07/26 16:56:25
おしえて。

フォームアプリのテキストボックスとかにデータバインディングで、
DataTable の要素を関連づけて入力値を管理したい。

ここで、テーブル中のレコードが1つの場合はいいんだが、複数あって
かつ、バインドするレコードを動的に変更したい場合ってのはどうすれば
いいのだろうか?

よくわからなかったので、

・バインド用に同じ構造のテーブルを用意して
・そこにレコードをひとつだけ作り
・そのレコードに元テーブルの任意のレコードの値をコピーする
・フォーム終了後にもとのテーブルのレコードに値をコピーし直す

方法で使おうとも思ったのだけど、もっと直接的な方法がありそうな気がする。
いかがだろうか。教示いただけると嬉しい。

667:デフォルトの名無しさん
09/07/26 17:08:13
>>666
ここよりもC#、VB、ADO.NETスレあたりで聞いたほうが早いと思うよ。

668:デフォルトの名無しさん
09/07/26 18:06:25
そう? じゃ、C# のスレに移動するよ。
thx

669:デフォルトの名無しさん
09/07/27 23:44:45
質問です。
自転車って制限速度が無いと聞いたことがあります。
一方で、系車両は制限速度30km/hと聞いたことがあります。
自転車に関してはどうなのでしょうか。
自転車に速度計装着の義務付けが無い以上、
制限速度自体、無意味なことだと思うのですが。


670:デフォルトの名無しさん
09/07/27 23:50:41
無料で難読化できるソフトはありますか

671:デフォルトの名無しさん
09/07/28 00:34:28
ある

672:デフォルトの名無しさん
09/07/28 10:55:16
>>669
軽車両には車両種別による速度制限はありません。標示の制限に従ってください。

673:デフォルトの名無しさん
09/07/28 14:57:05
C++/CLI的には見られたくないところはネイティブコードで書けばいい

674:デフォルトの名無しさん
09/08/04 06:16:44
PictureBoxの左上を座標(0,0)としてマウスでクリックしたときの
PictureBoxの左上からのオフセット座標を取得したいのですが
いい方法ありますでしょうか。


675:デフォルトの名無しさん
09/08/04 06:47:44
>>674
取得したいも何も、MouseClickイベントで受ければ
MouseEventArgsに入ってるだろ。

676:デフォルトの名無しさん
09/08/06 06:26:04
質問です。
初期化時にPictureBoxに格子上の線を描画したあと、PictureBox内をクリックした場所に図形を描画したんですけど
再度クリックしたときにその図形を消したい場合は一度RefreshやClearなどをしたあとに格子上の線・図形は再度描画
するしか方法ないですよね。

677:デフォルトの名無しさん
09/08/06 06:27:14
___
←樹海| 
 ̄|| ̄ ┗(^o^ )┓三
 ||    ┏┗  三
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄



678:デフォルトの名無しさん
09/08/06 09:04:47
>>676
毎回描画し直します。
C++/CLIに限らない.NET Frameworkの使い方についてはC#かVB.NETのスレで質問することをお勧めします。
(C++/CLIにしかない機能を使わないならC++/CLIを使うこと自体お勧めしません)

679:デフォルトの名無しさん
09/08/12 11:52:55
質問です。
プロジェクトの新規作成で自動的に作成されるFrom1.hですが、
簡単に一括で、それらしい名前(CalcMainForm.h等)に変換で
きる方法はありますか?(自動生成されるコード内のClass名称
なども追従したい)

今は、手作業でファイル名の変更後、コード内の名称を置換しています。


680:デフォルトの名無しさん
09/08/12 12:10:44
VSのアドインとかでリファクタリングのツール探してみては

681:デフォルトの名無しさん
09/08/12 18:06:34
ファイル名はファイルのプロパティの名前
クラス名はクラスのプロパティのName
簡単と感じるかは人による

682:デフォルトの名無しさん
09/08/15 10:36:57
俺はウィザード直後に即削除。
新しく任意のFormクラスを作成→コードゴリゴリw

683:デフォルトの名無しさん
09/08/23 00:11:09
クラスを参照渡しするときに、mainで渡すと問題なく実行できるのですが
クラスの中で渡すと下記のエラーが発生してしまいます。

"演算子 '%' は、値型または ref クラスのインスタンスにのみ適用できます"

このエラーを回避するためにはどのようにすればいいでしょうか?


おk:
main(){
A^ a;
B^ b;
b->(%a);
}

マズー:
ref class Z{
A^ a;
B^ b;
b->(%a);
}


684:デフォルトの名無しさん
09/08/23 01:50:23
クラスの中に処理は直接書けない。メソッドの中に書く。
エラーを回避とかそういう次元の問題ではないのでまずはC#かC++を一通り勉強するべき。

685:デフォルトの名無しさん
09/08/23 02:10:25
これからC++/CLIを勉強しようと思うんだけど
どんな本読んだらいいのかしら?^^

686:デフォルトの名無しさん
09/08/23 02:21:17
VisualStudio2008ExpressEditionをイジリ倒す。

687:デフォルトの名無しさん
09/08/23 02:24:20
C++とC# (またはVB7-)をどのくらい理解してるかでいろいろ違ってくる。
両方まだなら手を出さないほうがいい。

688:デフォルトの名無しさん
09/08/23 06:57:30
というかC++もC#も両方使いこなせる人にしかC++/CLIを使う意味がないし使う必要もない。

689:デフォルトの名無しさん
09/08/23 07:16:52
C++はGOF本を読むレベルっす。オブジェクト指向設計も任せてネ★
MFCはまぁそこそこ。ATLはさっぱり。WTLはみたこともない。

C#? なにそれ?
マイクロソフトローカルな糞言語になんてまったく興味ねぇんだよっ

690:デフォルトの名無しさん
09/08/23 08:07:39
C++/CLIのスレで、よくそんなことがいえるな。
C++/CLIがよりいっそうマイクロソフトローカルな糞言語なのを理解しているのか?

691:デフォルトの名無しさん
09/08/23 09:37:50
所詮はつぎはぎで緊急避難するときだけ使う補助言語だからな

692:デフォルトの名無しさん
09/08/23 10:16:28
ワロタ
>>689は自分がどこに書き込んだのかもわかってないのか

693:デフォルトの名無しさん
09/08/23 11:20:47
自分は C++/CLI については 実践C++/CLI 極めるための基礎と実用テクニック を読んだだけだな。
あとは C# まで含めてどうとでもなったよ。

ただ。最初のコードを見る限り、基本からわかってないと思うけど。
C++ がどうとかではなくて、プログラミングの基礎からって意味で。
ちゃんと基礎からやった方が、結局は時間の節約になると思う。

694:デフォルトの名無しさん
09/08/23 22:41:47
つまり、。NETについて学ぶにはまずC#を習得して来い…と。
C#…なぁ。Javaならまだ学ぶ気あるんだけど。
(J++1.0が出た当時にちょろっとかじったから、基本はあるんだよ^^
 でも最近はJava5とかいうのらしいから、勉強しなおしかな^o^;)

どうせ5年もしないうちに「なかったこと」にされるような言語なんて
学ぶだけ資源の無駄だしなぁ。どうしようかなぁ。ああー。

695:デフォルトの名無しさん
09/08/23 22:51:22
C#が世に出て既に8年ほどたつが、まだなかったことにはなってないな
C++/CLIのほうがよほど…

696:デフォルトの名無しさん
09/08/23 23:00:41
これって何に使うの?
C++Builderの代わり?

697:デフォルトの名無しさん
09/08/23 23:15:50
てか、基礎のある人間なら、わざわざ覚えるってほどのモンでもないだろ。
MFC わかるんだよね?

698:デフォルトの名無しさん
09/08/23 23:20:23
J++のWFC、delegate、J/Directを理解してるならそれはそれですごいな。
delegateはC#のとも一味違うぞ。


699:デフォルトの名無しさん
09/08/24 06:41:25
C#やったことなくてもC++/CLIは使えるかもしれないけど
C#で.NETの流儀に慣れてないと.NET的にはとんでもないコードが確実に出来上がる

700:デフォルトの名無しさん
09/08/24 12:49:28
>>699
慣れてないせいか、Disposeルールが
なんか気持ち悪い。


701:デフォルトの名無しさん
09/08/24 16:13:03
>>700
あれはネイティブなC++でいうところの単なるデストラクタなんだが……

702:デフォルトの名無しさん
09/08/24 19:24:05
そう思っているなら確実に
>.NET的にはとんでもないコード
を書いてるな。


703:デフォルトの名無しさん
09/08/25 21:04:58
MFCのDLLがあってCLIでラップしてVB.NetとC#で利用しようとしてるんですが
unsigned char *の配列データを受け渡しするところがあって
VB.NetだとこれはByte()になるんだろうけどどういう変換すればいいのでしょう?
Byte()の引数ってCLI側での表記方法も分からないし

704:デフォルトの名無しさん
09/08/25 22:13:16
Byte[] に変換するなら、

 cli::array< System::Byte >^ a = System::Text::Encoding::GetEncode( "エンコードの種類" )->GetByte( "String型の文字列" );

ただ、Byte[] に変換したいのではなくて、String から char* に変換したいんだろうから、だったら、

 ::sprintf( a, "%s", "String型の文字列" );

‥‥本当に出来る。w
正しい?方法は StringToHGlobalAnsi でぐぐれ。

705:デフォルトの名無しさん
09/08/25 22:25:20
いえ、画像データなんで本当にバイト列が必要なんです

706:デフォルトの名無しさん
09/08/25 22:25:55
バイナリデータであるByte()やbyte[]を渡したいだけかもしれないぞ。
もしそうなら、cli::array<System::Byte>^型が対応するのでこれを使えばいいだけ。
自分はcli::array<unsigned char>^と書く方が好みだがまあどっちでも同じ。

707:デフォルトの名無しさん
09/08/25 22:36:09
unsigned char* だから普通に byte 配列だろなんとなく。
分かりにくいので以下の説明は BYTE* で行くな。

まず、BYTE* -> byte[] はそのままでは無理。byte[] を
構築してコピーする。

BYTE source[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
array<Byte>^ arr = gcnew array<Byte>(10);
pin_ptr<Byte> p = &arr[0];
memcpy(p, source, 10);

次に、byte[] -> BYTE* は可能。上でやってるが、pin_ptr でおk。

pin_ptr<Byte> p = &arr[0];

ちなみに、VB だったら GCHandle で Pinned しなさい。IntPtr が
取れる

まとめ。なんで両方の方向の説明したかというと、コピー発生させ
たくないならマネージで byte[] なバッファ作成して(ここポイント)、
それ使うといいよみたいな。


708:デフォルトの名無しさん
09/08/25 22:42:03
いやcli::arrayってByte()と同じ形なの?
双方向でやりとりするんだけどコピーではなくて共有して書き出すからポインタを変換しないといけない
例えば
DLL側
array<Byte> ^GetData();

VB側
dim bytes as Byte[] = dll.GetData()
bytes[0] = 255;

みたいな使い方がしたい

逆にVB側のByte[]を渡してDLLに中身を書き込ませるような処理もある

ポインタのキャストがうまくいかないんだけどどうすればいいの?

709:デフォルトの名無しさん
09/08/25 22:54:02
cli::array< Byte >^ と Byte[] は同じ型だよ。
言語による表現の違いなだけ。

うまくいかないって、どんなエラーなわけ?

710:デフォルトの名無しさん
09/08/25 22:56:11
エラーというかキャストの仕方が分からない

711:707
09/08/25 22:56:55
>>708
・・・伝わってねぇかなぁ。その例なら

void Hoge(BYTE* p) {
 p[0] = 255;
}

void Piyo(array<Byte>^ arr) {
 pin_ptr<Byte> p = &arr[0];
 Hoge(p);
}

array<Byte>^ GetData() {
 array<Byte>^ arr = gcnew array<Byte>(10);
 pin_ptr<Byte> p = &arr[0];
 Hoge(p);
 return arr;
}

これで分かる?

712:デフォルトの名無しさん
09/08/25 23:01:19
>>711
GetDataは元がunsinged char *なんで
それごどうにかしてarray<Byte>^にしないといけないんですが

713:デフォルトの名無しさん
09/08/25 23:06:34
仮にarray<Byte>^にして渡した後ってVBのガーベージコレクタに殺されたりする?
それはまずいな

714:デフォルトの名無しさん
09/08/25 23:09:10
ということはVB->DLLの方向の時だけByte[]で受け取って
DLL->VBの時はラッパーDLLでアクセスを仲介するような関数を容易するべき?
例えばWriteByteみたいな関数を入れてDLLの保持してるメモリはVBでは触れないようにした方がいいの?

715:デフォルトの名無しさん
09/08/25 23:12:05
managed側のメモリはpinすればunmanaged側でいじれるが、
逆は出来ないんじゃないかなぁ。
基本はコピーになるはず。

unmanaged側でメモリを保持して、managedにはハンドルやクラスの形で
渡してやるのがセオリーだと思うよ。

716:デフォルトの名無しさん
09/08/25 23:13:32
なんかdllの仕様まで変更できるような話になってるが

717:デフォルトの名無しさん
09/08/25 23:20:04
メモリへのポインタを渡したいのか、ただデータを入れた配列を渡せればいいのかわかんね。
キャストの仕方っても、どんなところでなにをやろうとしてるのかわかんね。
dynamic_cast とかをキーワードにして調べてみたら? 自分で。

718:デフォルトの名無しさん
09/08/25 23:23:42
>>715
じゃあGetDataの部分はIntPtrを返してVB側でMarshal.ReadByteするのが適切?

>>716
CLIのラップDLLはGCの影響は受けないでしょ

>>717
ポインタを渡して中身を双方で共有して直接いじりたい
メモリは確保した方が解放するというのがルール

719:デフォルトの名無しさん
09/08/25 23:30:55
そう。

byte[](マネージバイト配列)ってのはマネージヒープに確保
されてそこにあるやつ。アンマネージで勝手に確保した
なぞの領域にあるところをさしたポインタってやつはそうじゃ
ないから当然変換できないしコピーするしかない。
マネージにあるやつのポインタ化(pin_ptr) は可能だが、逆は
無理。

結局シームレスにいじりたい領域はマネージ側で確保して
やるしかない。アンマネージポインタしかないんなら、コピーとか
マーシャリングとかしかない。

CLS 非準拠だと CLI は一応 T* みたいな形式も持ち運べは
するんだけどな。準拠させるためには IntPtr とかのやり取りと
なる。
…VB じゃなく C# ならそのポインタシームレスに使えるのだがな。

720:デフォルトの名無しさん
09/08/26 00:12:20
とりあえずラップDLLに読み書き専用の関数を持たせることで解決しました

721:デフォルトの名無しさん
09/08/26 14:58:37
プロパティの書き方で、ヘッダー(h)とソース(cpp)に分離する方法を教えてください

property float X
{
float get();
void set(float value);
}

ヘッダーにこのように書いたところ、
1>Vec3.obj : error LNK2020: 未解決のトークン (06000008) Fwm.Math.Vec3::get_X
1>Vec3.obj : error LNK2020: 未解決のトークン (06000009) Fwm.Math.Vec3::set_X

と言われたので、ソースに
float Vec3::get_X() { return 0; }

と定義してみたのですが書き方が間違っているようでコンパイルが通りませんでした

722:デフォルトの名無しさん
09/08/26 15:02:46
Vec3::X::get

723:デフォルトの名無しさん
09/08/26 15:10:32
そこかぁあああああああ!!!
ありがとう!!

724:デフォルトの名無しさん
09/08/26 15:14:58
インテリセンスに出ると思うんだがな

725:デフォルトの名無しさん
09/08/26 15:18:17
ところがどっこい出なかった

726:デフォルトの名無しさん
09/08/26 17:44:34
CLRでも<summary>指定したらインテリセンスにでまつか?

727:デフォルトの名無しさん
09/08/26 19:23:04
CLRが何だと思ってるのか詳しく聞かせてもらいたいな

728:デフォルトの名無しさん
09/08/27 02:05:29
C++/CLIとC++ネイティブのコード共存で開発してるんですが、

C++ネイティブクラスのメンバーをDataBindingするのって不可能ですか?

こんな感じでやってみたいのですが、System::Object^型にsrcを変換できずに
コンパイルエラーを吐きます。。。

class src {
public:
int m;
};

src = new csrc;
textBox1->DataBindings->Add(gcnew Binding("Text", src, "m"));

※textBoxのTextプロパティにintの値を設定しようとしているのは、例なのでスルーしてください。


729:デフォルトの名無しさん
09/08/27 06:51:20
中でリフレクション使ってるんだからできるわけがない
マネージクラスでプロパティとしてラップする

730:デフォルトの名無しさん
09/08/27 09:06:34
C++/CLIでも<summary>指定したらインテリセンスにでまつか?

731:デフォルトの名無しさん
09/08/27 09:20:42
出るよ

732:デフォルトの名無しさん
09/08/27 09:29:31
/// <summary>
/// クラス解説
/// </summary>
public ref class Test

って書いたら
<summary>
クラス解説
</summary>

って出た。<summary>消したら
クラス解説

って出た。なんか違うかな・・・

733:デフォルトの名無しさん
09/08/27 14:50:40
XMLドキュメントを出力するオプションは有効になってる?

734:デフォルトの名無しさん
09/08/27 16:29:59
ありがトン
なってませんでした
有効にしたら隣に~.xmlってのが出来たけど
やっぱりインテリセンスには出てこねぇ

735:デフォルトの名無しさん
09/08/30 12:38:18
デリゲートで関数のポインタを変数に渡そうとしてるんだけど
うまくいかない。

delegate void startCallback();
startCallback^ cb_start;

cb_start = gcnew startCallback(start);
fn = &cb_start;
cb_startがデリゲートの変数なのですが。
どうしたらいいでしょう?

736:名無しさん@そうだ選挙に行こう
09/08/30 12:40:23
&はいらん
^の意味解ってる?

737:735
09/08/30 12:50:37
>>736
確か似そうでした。
で、&を外してみたところ
error C2440: '=' : 'startCallback ^' から 'void (__clrcall *)(void)' に変換できません。
とかいうエラーが・・・。
どういう意味なのでしょう?



738:名無しさん@そうだ選挙に行こう
09/08/30 13:06:42
デリゲートと関数ポインタは別物だから。

739:名無しさん@そうだ選挙に行こう
09/08/30 16:30:32
>>735
fnやstartがどう定義されているか見えないけど、
fn = start でいいでない?

740:735
09/08/30 17:37:50
fn=start だと
error C3867: 'start': 関数呼び出しには引数リストがありません。メンバへのポインタを作成するために '&start' を使用してください
となって、fn=&startとすると737 のエラーとなるという。

fnもstartも同じ型でvoid (*dsfunctions::start)(void)なのだが、
c++/CLIだとだめらしい。

関数ポインタを渡したいだけなんですがどうしたもんでしょう?


741:名無しさん@そうだ選挙に行こう
09/08/30 18:03:47
もしかして、スタティックでない関数をその書式で使用しようとしてない?
ちがうなら、下みたいにすべきじゃね?

cb_start = gcnew startCallback( [startメンバを含むクラスインスタンス], start );

742:名無しさん@そうだ選挙に行こう
09/08/30 18:07:28
生のC++でもクラスのメンバ関数というか仮想関数の関数ポインタはカオスだからなぁ。

743:デフォルトの名無しさん
09/08/30 22:24:58
マネージドとネイティブでポインタや関数の互換はないから
関数自体をどちらかにラップするしかないだろう。
以下は関数ポインタとデリゲートの使用例
int native1(int x, int y) { return x+y; }
class Foo {
 public:
  static int nativeS(int x, int y) { return x+y; }
  int nativeV(int x, int y) { return x+y; }
};
delegate int MyCallback(int x, int y);
ref class Hoge {
 public:
 static int ManagedS(int x, int y) { return x+y; }
 int ManagedV(int x, int y) { return x+y; }
};


744:デフォルトの名無しさん
09/08/30 22:27:07
int main() {
  Hoge^hoge = gcnew Hoge();
  Foo foo;
  int (*f1)(int, int) = &native1;
  int (*f2)(int, int) = &Foo::nativeS;
  int (__thiscall Foo::*f3)(int, int) = &Foo::nativeV;
  //int (__clrcall *f4)(int, int) = &Hoge::ManagedS;
  //int (__clrcall Hoge::*f5)(int, int) = &Hoge::ManagedV;
  MyCallback^ f6 = gcnew MyCallback(Hoge::ManagedS);
  MyCallback^ f7 = gcnew MyCallback(hoge, &Hoge::ManagedV);
  System::Console::WriteLine(f1(100, 1));
  System::Console::WriteLine(f2(100, 2));
  System::Console::WriteLine((foo.*f3)(100, 3));
  System::Console::WriteLine(f6(200, 6));
  System::Console::WriteLine(f7(200, 7));
  return 0;
}
clrcall型の関数ポインタはdelegate作成時にしか使用できない。


745:デフォルトの名無しさん
09/08/31 01:47:06
^は「へ」って読むんだぞ

746:デフォルトの名無しさん
09/08/31 01:47:31
へー

747:デフォルトの名無しさん
09/08/31 10:30:09
実践C++/CLI 極めるための基礎と実用テクニック
アマゾンに入荷したね

748:デフォルトの名無しさん
09/08/31 20:52:39
え。出品者からお求めいただけます、じゃなくて?

749:デフォルトの名無しさん
09/09/01 03:42:45
うん。昨日見たときアマゾン新ピンが2800円ぐらいで売ってた
今見たら終わってたw

750:デフォルトの名無しさん
09/09/01 14:33:06
ていうかアマの技術書は一度の入荷数が少ない
近くの書店で取り寄せすればすぐだ

751:デフォルトの名無しさん
09/09/02 00:29:13
自分が確認したときにはすでになかったから、釣りかと思ったわ。
情報ありがとう。普通に取り寄せてみるよ。

752:デフォルトの名無しさん
09/09/02 01:16:03

C++の保守チームからCLIのチームに移ってきた新参者です。
C++の頃に良くみた無名名前空間でのリテラル文字定数の宣言

namespace {
const std::string EngFileName = "XXXX"
const std::wstring JpnFileName = L"XXX"
}

と同じことがしたくて

namespace {
const String^ EngFileName = "XXXX"
const String^ JpnFileName = L"XXX"
}

にしたらコンパイラ君に怒られてしまった。
もしかして、CLIではできない? 
const char* const EngFileName = "XXXX" みたいにC言語風に明記しないとだめなのでしょうか?

753:デフォルトの名無しさん
09/09/02 01:18:30
適切なクラス作って静的メンバにするのが.NETのやり方

754:デフォルトの名無しさん
09/09/02 01:33:56

そうなんですか!! ありがとう。
C++のころは、cppで使いまわすだけの定数をヘッダーに追加すると、
結構、コンパイルに時間がかかったので、無名名前空間に押さえ込んでました。

あ、そういえば自動生成されるコードもCLIは全部、ヘッダーに展開されますね。
無名空間はだめで、静的メンバであればOKってのが理解できないので、
ちょっくらテストしてきます。 注意点とかあれば教えていただけますか?

755:デフォルトの名無しさん
09/09/02 03:23:27
>>754
なんか分かってなさそうなので念のために言っておくけど、
適切なクラスというのはref classのことだぞ。


756:デフォルトの名無しさん
09/09/02 08:44:54
>754
const は String^ にはつけられないから literal 使え

757:デフォルトの名無しさん
09/09/02 15:51:30
initonlyも忘れないで。外へ公開するメンバなら特に。

758:デフォルトの名無しさん
09/09/02 18:24:19
initonly と literal はアセンブリ化したときの文字列確定のタイミングが違うから気をつけろ

759:デフォルトの名無しさん
09/09/02 22:48:46
やば。initonly を完璧に忘れてた。。。

760:754です。
09/09/04 19:08:41

ありがとうございます。
準備した参考書では、literalもinitonlyも明記がなかったので、なかなかできませんでしたが、
ようやくテストできました。(結果もOKでした。)

ただ、literal と static const の違いだけが分かりませんでした。
どちらも同じ結果になるので・・・。
CLIで追加された宣言なので、literalを使えば良いのかな?

それにしても、CLIの情報は探すのが大変ですね・・・。みなさんはどうしてますか?(どうやって覚えました?)

761:デフォルトの名無しさん
09/09/04 20:26:10
>760
String^ は追跡参照なのでポインタのようにアドレスが一定ではない。だから、const
指定できない。(const が有効だとGCがString^を移動できない)その代わりに literal が
あると思っていい

762:デフォルトの名無しさん
09/09/04 20:38:18
literalって単なるアセンブリのメタデータだし

763:デフォルトの名無しさん
09/09/13 01:12:57
>>879
パレスチナ問題って深刻だね。

764:デフォルトの名無しさん
09/09/13 04:02:10
C++/PLO
うむ、一文字しかあってない

765:デフォルトの名無しさん
09/09/14 19:53:24
pin_ptrのようにオブジェクトの移動を制限する方法って他にないでしょうか
スコープを抜けてもずっと固定していたいんですが

766:デフォルトの名無しさん
09/09/14 20:02:36
GCHandleを割り当てる

767:デフォルトの名無しさん
09/09/16 22:06:03
C++からの移植で下位のような変換を行ってみました。

clss NameHolder
{
   NamaInfo _Name;
public:
   NamaInfo getNameInfo();
}

ref clss NameHolder
{
NamaInfo^ _Name;
public:
NamaInfo^ getNameInfo();
}

768:デフォルトの名無しさん
09/09/16 22:10:18
C++からの移植で下位のような変換を行ってみました。

// C++の場合
clss NameHolder
{
  NamaInfo _Name;
public:
  NamaInfo getNameInfo();
}

// CLIの場合
ref clss NameHolder
{
  NamaInfo^ _Name;
public:
  NamaInfo^ getNameInfo();
}

C++の場合だと、getNameInfo()で取得したNamaInfo を呼び出し元で変更しても、
元の値(NameHolder)は値が変わりませんが、 CLIの方だと変わってしまいます。
ハンドルだからといわれそうですが、CLIで値を保持するクラスより、クラス側の値を取得するのは
一般的にどのように実装すべきでしょうか?

769:デフォルトの名無しさん
09/09/16 23:09:46
value class使え

770:デフォルトの名無しさん
09/09/17 02:04:27
ありがとうございます。
value class を使用することで、目的の動作ができました。
ただ、疑問が残りまして、該当クラスには、セッター関数もありまして

(1) void setNameInfo( NamaInfo^ Name) { _Name = *Name; }
(2) void setNameInfo( NamaInfo& Name) { _Name = Name; }
(3) void setNameInfo( NamaInfo Name) { _Name = Name; }

もどれも同じ挙動でした。(3)にすると、実体がコピーされて遅そうなので、
(1)か(2)かと思ったのですが、一般的にはどちらを使うものなのでしょうか?

771:デフォルトの名無しさん
09/09/17 02:08:28
実体コピーしなきゃ結局他でNameInfo変更したときに影響するだろ…

772:デフォルトの名無しさん
09/09/17 02:23:39
便乗ですまない

>>770の(1)はマネージでないとダメで、(2)はアンマネージでないとダメだと
思っていたんだけど、両方とも許される状況っていうのはあるもんなの?

773:772
09/09/17 02:37:45
value classだと(2)は問題なく参照となり、
(1)はボクシングが行われた上で、ハンドルを取得できる、と考えたけどあってるのかなぁ。
難しいなぁ

774:デフォルトの名無しさん
09/09/17 02:41:02
public value class NameInfo
{
   public: property Int32 ID;
};

public ref class NameHolder
{
   NameInfo _Name;
public:
  NameInfo get(){return _Name;}
// void set(NameInfo^ Name ){_Name = *Name;}
// void set(NameInfo& Name ){_Name = Name;}
  void set(NameInfo Name ){_Name = Name;}
};

int main(array<System::String ^> ^args)
{
  NameInfo Name;
  Name.ID = 10;
  NameHolder Holder;
  Holder.set(Name);
  NameInfo Buf1 = Holder.get();
  Console::WriteLine(Buf1.ID);
  Name.ID = 20;
  NameInfo Buf2 = Holder.get();
  Console::WriteLine(Buf2.ID);
  return 0;
}
どれも結果は 10、 10と表示され、値は登録後の値は変わりませんでした。
根本的に、なんか勘違いしてますかね?

775:デフォルトの名無しさん
09/09/17 02:49:44
メンバがいつの間にかハンドルじゃなくなったな

776:デフォルトの名無しさん
09/09/17 03:05:00
NameInfo^ _Name; これに変更。
NameHolder() { _Name = gcnew NameInfo(); } これ追加

してやって見ました。結果は同じでした。C++からハンドルが一つ増えただけで、こんなにも苦労するとは・・・・

777:デフォルトの名無しさん
09/09/17 03:10:40
もとのC++の記述と同じようにかきゃいいと思うけどな
value classならほぼ変わらんし
移植って時点で思想とか意味ないだろうし

778:デフォルトの名無しさん
09/09/17 03:19:20
元のコードにあわせてハンドルじゃなくしたのかと思ったけど、あっさりハンドルに戻すとか
ほんとに移植しようとしてるのかが疑問

779:デフォルトの名無しさん
09/09/17 03:54:00
>>770
ちなみに、ネイティブなC++だったら、そのsetの引数の型は、NameInfoかconst NameInfo&にするとこだよね。

自分だったら、NameInfoにするかなあ。コピーのコストが心配っていうならそもそも値型にしないし。
読み取りだけの引数にconst付けないのは嫌だ。

値型の場合、T& → T%、T* → interior_ptr<T>へと機械的に変換すればいい。
その上で、他言語で使えないのでconstは削除し、値型のハンドルも使わないのが自分の方針。

ちなみに、(1)の値型のハンドルで、>>774のようにボックス化されていない(ハンドルでないもの)を実引数にする場合、
ボックス化(ようは新しくメモリ確保してそこへ実引数をコピー)が行われるので(3)より遅いよ。

780:デフォルトの名無しさん
09/09/17 04:03:11
>>779
横からごめん
> 他言語で使えないのでconstは削除
というのはどういうこと?

781:デフォルトの名無しさん
09/09/17 04:20:29
>>780
C#などからそのメソッドを呼ぶ場合、あたかもconstはなかったかのように無視される。
そのため、自分はC++/CLIは他言語から呼び出すことを前提に使っているので、
C++/CLIの段階でpublicな型のpublicなメソッドの引数・戻り値にはconstを付けようと思わないというだけのこと。

つまり、これは自分1人の考えなんで、気にせずconst使うという人も中にはいると思う。

782:デフォルトの名無しさん
09/09/17 04:29:23
>>781
なるほど。勉強になりました。

783:774です。
09/09/17 04:39:15

いろいろとありがとうございます。
先輩にきいて、値を保持したいのであれば、このクラスを移植すれば良いとともらったソースを移植中です。
中身を見ると、シングルトン形式で値を保持しているようです。
C++であれば const NameInfo& Name なので、const NameInfo% Name にしたらコンパイラ君に怒られて
パニックになってしまいました。 
C++の時は、メンバー関数の後ろをはじめ、constをつけるように、強く教育を受けたので、CLIでもかんばって
つけようとするとことごとく怒られて・・・・。
NameInfo という値で渡すのがよさそうなので、これでいって見ようかと・・・。
教えていただいた 機械方式 NameInfo% にしたいですが、先輩に % は関数内で値を変えるとき意外は使うなといわれて・・・。
くそー 何でconst NameInfo%  て読み取り専用にできないだよ!!!!

784:デフォルトの名無しさん
09/09/17 07:46:38
constが付いていたら、自動生成した読み取り専用ラッパーに包んで返す。
……とかどうなんだろう。やっぱ駄目かなあ。

785:デフォルトの名無しさん
09/09/17 08:47:15
プロパティでgetterのみにすればいいんじゃないか?

786:デフォルトの名無しさん
09/09/17 10:14:48
値型^って普通使わないよ
一番効率悪いし他の言語では全く使えない

787:デフォルトの名無しさん
09/09/24 23:24:35
String型だけなんで^なしで宣言出来ないんだろう…
あとshortの列挙型に-32768が使えないのもわからん
C#なら通るのに

788:デフォルトの名無しさん
09/09/24 23:27:32
String型がcharの配列なので。
shortの-32768(全ビットon)は未定義値の代わりなので。

789:デフォルトの名無しさん
09/09/24 23:38:51
即レスありがとう
Stringの内部構造までは見たんだけど、つまりC++/CLIでは配列はスタックに作れないってことなのかな

790:デフォルトの名無しさん
09/09/25 04:34:30
動的にサイズを変えられるんだからヒープまたはマネージドヒープと考えるのが妥当なんじゃないの

791:デフォルトの名無しさん
09/09/25 07:45:38
^なしに記述しているのだって、別にスタックに配置している訳じゃないし

792:デフォルトの名無しさん
09/09/30 15:44:34
String型だけなんで^なしで宣言出来ないんだろう…

ref class だから

793:デフォルトの名無しさん
09/10/01 00:51:52
C++のRAIIパターンでDispose持ちの参照型を扱おうって意図だから
参照型でもこれはOKなんよ。
実際はDisposeのシグネチャを持ってる必要もないんだが。

ただ何故かStringとarrayは宣言できんのね。

794:デフォルトの名無しさん
09/10/06 00:13:56
deleteしたオブジェクトのファイナライザって呼ばれないの?
C++/CLIのデストラクタ=C#のDisposeだと思ってたんだけど

795:デフォルトの名無しさん
09/10/06 00:31:17
C#でもDisposeしたときはGC.SuppressFinalizeでファイナライザの呼び出しを抑制するが?

796:デフォルトの名無しさん
09/10/06 11:24:38
ファイナライザの呼び出しが有効になってるとGCのパフォーマンスに悪影響を与える。
明示的にDisposeが行われた後はファイナライザ呼び出しは不要なはずなので
ファイナライザを呼び出さないようにGCに指示するようになってる。
アンマネージリソースを直接持ってない限りはファイナライザ(!の方)は定義しない方がよい。

797:デフォルトの名無しさん
09/10/06 13:17:58
~ClassA()や!ClassA()はDispose()やFinalizerそのものではない。
正確にこのコードになるわけじゃないのだけれどイメージとして捉えて欲しい。
 ~ClassA() { }
 !ClassA() { }
上2つを使っていると、ここからはコンパイラが生成する。
 void Dispose(bool disposing) {
   if (disposing) ~ClassA(); else !ClassA();
 }
 void Dispose() {
   Dispose(true); GC.SuppressFinalize(this);
 }
 void Finalize() {
   Dispose(false);
 }



798:デフォルトの名無しさん
09/10/09 17:38:36
C/C++室より、案内されてこちらのスレに来ました。


void test(int x[]){cout << sizeof x << endl;return;}

int main(array<System::String ^> ^args)
{
  int x[] = {1,2,3,4,5};
  test(x);
  cout << sizeof x << endl;
}

■出力結果
4
20

なんで両方とも20にならないんでしょうか?

799:デフォルトの名無しさん
09/10/09 17:58:20
CLI一切関係ないな
仮引数が配列表記でも実際はポインタとして渡される

800:デフォルトの名無しさん
09/10/09 18:15:42
>>799
>CLI一切関係ないな
失礼しました。
void test(int x[]) が void test(int* x)として解釈されるという事ですね。
誘導元のほうでも親切な方が教えてくれました。

ありがとうございます。

801:デフォルトの名無しさん
09/10/10 02:32:29
ハンドル使ってるから脊髄反射したんだろう

802:デフォルトの名無しさん
09/10/10 16:37:37
>>801
つーか内部的にMSIL使ってる言語は気持ち悪いんだよ
全部こっちに回すから頼んだ

803:デフォルトの名無しさん
09/10/10 23:57:23
出力結果から想像できるだろうに。
近頃の子は自分で考えるってこと、しないのかねぇ。

804:デフォルトの名無しさん
09/10/11 09:13:05
void func(int *a);
とかアドレスを引数にする昔の関数に
int b;
func(&b);
などとすると、
cli::interior_ptr<Type>' から 'int *' に変換できません。
とかいうエラーが出てしまいます。
どうしたらいいでしょうか?

805:デフォルトの名無しさん
09/10/11 10:42:48
reinterpret_cast<Int32*>(&b)

806:デフォルトの名無しさん
09/10/11 11:00:48
つーかその例でそのエラー出るか?

807:デフォルトの名無しさん
09/10/11 12:29:34
>>804
pin_ptr<int> p = &b;
func(p);

808:デフォルトの名無しさん
09/10/11 13:03:52
>>804
int bがref classのメンバーなのかな。ローカル変数だったら出ないだろ。

809:デフォルトの名無しさん
09/10/11 13:24:52
C++/CLIの仕様書ってある?
C++で言うとISO/IEC 14882:2003みたいな奴

それがあれば簡単な質問ぐらいならC++スレでレスしてやってもよい

810:デフォルトの名無しさん
09/10/11 13:25:46
仕様書じゃなくて規格票だったorz

811:デフォルトの名無しさん
09/10/11 14:14:27
ぐぐるかecma行って372見てこい

812:デフォルトの名無しさん
09/10/11 14:33:33
URLリンク(blogs.wankuma.com)

だめじゃんISO規格じゃない
まあecmaのを参考にするか

813:デフォルトの名無しさん
09/10/11 15:50:25
>だめじゃんISO規格じゃない 

これが言いたかったのか(笑

814:デフォルトの名無しさん
09/10/12 03:21:26
IETF > Ecma > ISO

815:デフォルトの名無しさん
09/10/12 10:19:51
日本の車もウインカーレバーが右で、ISO規格と違うからな。
イギリスは右ハンドルでもISO通りに左なのに。

816:デフォルトの名無しさん
09/10/12 15:25:50
要するにISOってオナニー規格か

817:デフォルトの名無しさん
09/10/13 18:48:03
そういえばC#のコンパイラの言語バージョンを選ぶオプションは
ISO3.0みたいな表記だったな

818:デフォルトの名無しさん
09/10/14 09:55:30
現在自民党が民主党を批判していること、
おまえが言うか、とあきれている。

819:デフォルトの名無しさん
09/10/14 11:20:17
ヤトウの仕事だから。

820:デフォルトの名無しさん
09/10/14 19:29:43
>>818
今まで民主党が批判してた事を民主党がやったりもするわけですよ
ヨトウになるとはそういうこと

821:デフォルトの名無しさん
09/10/14 22:39:15
>>818
スレタイを読めないおまえが言うか、とあきれている。

822:デフォルトの名無しさん
09/10/15 18:55:56
Side-by-sideでexe作ろうとしてるけど
M$っていろんな意味で終わってるなw
保険屋の仕事を作るようにしてあるシステムと同じだろこれw
仕事にしてる奴らは悲惨だろうな。
後には何も残らん。

823:デフォルトの名無しさん
09/10/16 02:11:13
とりあえずMS叩くと出来る奴っぽく見えるよなw

824:デフォルトの名無しさん
09/10/21 01:14:26
エラーがなくせずに困っています。
関数のポインタを渡すときに
error C3867: 'SM::f': 関数呼び出しには引数リストがありません。メンバへのポインタを作成するために '&SM::f' を使用してください
などとエラーになってしまいます。
Move(f);
のfが関数なのですが・・・。
どうすればよいでしょう?



825:デフォルトの名無しさん
09/10/21 09:54:36
ほんとにわかってないのか、これなのかはソース見せてもらわないと判断できないが・・・
URLリンク(msdn.microsoft.com)(VS.80).aspx

826:デフォルトの名無しさん
09/10/21 17:56:32
ダウンロードの詳細 : Visual Studio International Feature Pack 2.0
URLリンク(www.microsoft.com)

827:デフォルトの名無しさん
09/10/21 18:14:59
1.0系でとりあえず行くのかと思ったらいきなり2.0かよw

828:デフォルトの名無しさん
09/10/21 18:34:30
6月の時点で2.0ベータが出てただろ

829:デフォルトの名無しさん
09/11/04 12:57:39
てす

830:デフォルトの名無しさん
09/11/30 21:33:43
TreeViewで追加したノードAとノードAの子のノードBのチェックボックス
にチェックしようと思ったんですが以下のコードではうまくいきませんでした。
各ノードの子が存在するかを調べてチェックする以外の方法でコードがすっきりする方法ありますか?

int countMax = treeView_Action->GetNodeCount(true);
for ( int i = 0; i < countMax; ++i )
{
 treeView_A->Nodes[i]->Checked = true;
}


831:デフォルトの名無しさん
09/11/30 21:42:40
> 各ノードの子が存在するかを調べてチェックする
これで十分すっきりすると思うが
再帰を知らないとか言うのか?

832:デフォルトの名無しさん
09/12/11 16:21:58
どなたかくだすれスレを立ててくだすれ

833:デフォルトの名無しさん
09/12/11 16:33:42
こんだけ過疎ってんだから無駄だろ
聞きたきゃここで聞けばいい

834:デフォルトの名無しさん
09/12/12 02:21:57
失礼します。
Iniファイルの読み書きを行いたいのですが、うまくいきません。
エラーは出ないのですが、ファイルが作成されないので・・・。
すいませんが、どこが間違っているのか教えてください。
よろしくお願いします。

using namespace System::IO;
using namespace System::Text;
using namespace System::Reflection;
using namespace System::Runtime::InteropServices;

[DllImport("kernel32.dll")]
static UInt32 GetPrivateProfileString(String^ lpAppName, String^ lpKeyName, String^ lpDefault, StringBuilder^ lpReturnedString, UInt32 nSize, String^ lpFileName);
[DllImport("kernel32.dll")]
static UInt32 WritePrivateProfileString(String^ lpAppName, String^ lpKeyName, String^ lpDefault, StringBuilder^ lpReturnedString, UInt32 nSize, String^ lpFileName);

// Iniファイル読み込み
private: System::Void IniRead(System::Void){
String^ path = Path::Combine(Path::GetDirectoryName(Assembly::GetEntryAssembly()->Location), L"test.ini");
StringBuilder^ sb = gcnew StringBuilder(1024);
UInt32 ret = GetPrivateProfileString(L"DB_INFO", L"SERVER_NAME", L"default", sb, sb->Capacity, path);
System::Console::WriteLine(sb->ToString());
}
// Iniファイル書き込み
private: System::Void IniWrite(System::Void){
String^ path = Path::Combine(Path::GetDirectoryName(Assembly::GetEntryAssembly()->Location), L"test.ini");
StringBuilder^ sb = gcnew StringBuilder(1024);
sb->Append("TestVal");
UInt32 ret = WritePrivateProfileString(L"DB_INFO", L"SERVER_NAME", L"default", sb, sb->Capacity, path);
}

835:834
09/12/12 02:26:25
開発環境を書くのを忘れてました。
WindowsXP SP3
Visual Stadio 2010 Beta2
です。

836:デフォルトの名無しさん
09/12/12 02:34:25
C++/CLIでわざわざDllImport?

837:デフォルトの名無しさん
09/12/12 08:08:41
/clr:safe なのでは

838:デフォルトの名無しさん
09/12/12 08:25:36
WritePrivateProfileStringの引数がなんでGetPrivateProfileStringと同じなんだよ。
MSDNをみろよ。

BOOL WritePrivateProfileString(
  LPCTSTR lpAppName,  // セクション名
  LPCTSTR lpKeyName,  // キー名
  LPCTSTR lpString,   // 追加するべき文字列
  LPCTSTR lpFileName  // .ini ファイル
);

>>833の手前初心者スレに池とはいえんな(笑


839:デフォルトの名無しさん
09/12/12 13:48:26
初心者スレではCLIスレへ池と言われ
CLIスレでは初心者スレへ池と言われ・・・

840:デフォルトの名無しさん
09/12/12 18:28:17
>>833

斬新だな

841:sage
09/12/12 20:27:27
今まで

Diagnostics::Debug::WriteLine("文字列");
Diagnostics::Trace::WriteLine("文字列");

の違いで Debug は、Debug版コンパイルのみに出力され、
Traceは Debug/Release版 双方で出力される・・・と思って、

Debug::WriteLine("文字列");

を使ってきました。しかし、先ほど

DefaultTraceListener^ dtl = (DefaultTraceListener^)Debug::Listeners["Default"];
dtl->LogFileName = "C:/debug.txt";

としてみると、Release版でも C:/debug.txt に出力されて
しまいました。

Debug版でのみ、出力させるには

#if defined(_DEBUG)
Diagnostics::Debug::WriteLine("文字列");
#endif

としないとダメなのでしょうか?

842:デフォルトの名無しさん
09/12/12 21:21:48
>>841
Conditional属性ついてるから、その認識で間違ってないはずだが

843:デフォルトの名無しさん
09/12/12 21:25:27
Trace::Listeners
Debug::Listeners
は同じコレクションをポイントしていて、片方を変更すればもう片方も変更になる。


844:デフォルトの名無しさん
09/12/12 21:48:40
>>843
そういう問題じゃないだろ

845:デフォルトの名無しさん
09/12/12 21:52:12
>>841-842
C++/CLIではC#やVB.NEtのようにConditionalAttributeを認識しないから、
自分で#ifdef使って、呼び出しを消す必要がある

846:841
09/12/13 01:26:19
>>845

ConditionalAttributeを認識しない・・・んですね。
初耳です。勉強になりました。


>自分で#ifdef使って、呼び出しを消す必要がある

とても面倒ですね。自前のDEBUG関数を定義して、
それでまとめて処理させるべきなんでしょうかね。

847:834
09/12/13 02:10:44
>>838
遅くなってすいません。
無事にできました、ありがとうございます。

848:デフォルトの名無しさん
09/12/13 09:22:00
>>846
関数を使わなくても、#define でいいじゃないか
#ifdef DEBUG
#define DEBUGOUT Trace::~
#else
#define DEBUGOUT
#endif


849:デフォルトの名無しさん
09/12/13 09:28:22
>>846
ちなみに、.NET2からは(Debug|Trace)::WriteLineよりはTraceSourceを使う方がいいことになってる

850:デフォルトの名無しさん
09/12/16 02:13:09
VS 2005で、System::Windows::Forms::ToolStripを継承して、'MyToolStrip' クラスを実装しました。
ビルドすると、ツールボックスの中にMyToolStripが現れましたが、
Formに貼り付けようとすると、

ツールボックス アイテム 'MyToolStrip' の読み込みに失敗しました。アイテムはツールボックスからから削除されます

と表示され、ツールボックスから消えてしまいます。



それならと、既に貼り付けてあるFormクラスの中のToolStripを、MyToolStripへコードを直接書き換えて
みました。コンパイルも通り、実行もできるのですが、FormのデザインをGUIで開こうとすると

デザイナの読み込み時に 1 つ以上のエラーが発生しました。

C++ CodeDOM parser error: Internal Error

が表示され開けません。.NETの標準クラスを継承して、フォームデザイナで使いたいのですが、
どうすれば良いのでしょうか?

851:デフォルトの名無しさん
09/12/16 06:08:01
とりあえず、これで動いてる。どこかで下手打ってるのだろう。
ソースをさらせ。
public ref class MyToolStrip : System::Windows::Forms::ToolStrip { };



852:デフォルトの名無しさん
09/12/16 06:10:35
コンストラクタで例外投げてるとかじゃね

853:デフォルトの名無しさん
09/12/16 08:35:33
これはC#でも同じだが、Controlのコンストラクタに副作用があると
デザーなーの表示に失敗することがあるよ。

854:デフォルトの名無しさん
09/12/16 11:47:21
まあそういう場合は、親がデザイナかどうか判定して挙動を変える必要があるわな

855:850
09/12/16 22:16:49
プロジェクトをWindowsフォームで新規作成して、

>>851

のクラスを定義した所、問題無くツールボックスの中にMyToolStripが現れ、
フォームに貼り付けできました。

プロジェクトのランタイムプロパティが
「純粋 MSIL 共通言語ランタイム サポート (/clr:pure)」の場合問題ありませんが、
当方「共通言語ランタイム サポート (/clr)」で開発をしており、
その場合、850で書いたような状況になります。ノートPCのサブ開発環境でも
再現するので、再現性はあります。

皆さんの所では問題ありませんか?

856:デフォルトの名無しさん
09/12/16 22:18:00
知るか
再現云々言うんだったらまずソースを出せ

857:850
09/12/16 22:31:48
>>856

Windowsフォームを新規作成して、ランタイムを
共通言語ランタイム サポート (/clr)に変更するだけなのですが・・・。

ソースを貼ります。

Form1.h

#pragma once


#include "test.h"

namespace test {

using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;



858:850
09/12/16 22:32:30
Form1.hの続き
/// <summary>
/// Form1 の概要
///
/// 警告: このクラスの名前を変更する場合、このクラスが依存するすべての .resx ファイルに関連付けられた
/// マネージ リソース コンパイラ ツールに対して 'Resource File Name' プロパティを
/// 変更する必要があります。この変更を行わないと、
/// デザイナと、このフォームに関連付けられたローカライズ済みリソースとが、
/// 正しく相互に利用できなくなります。
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: ここにコンストラクタ コードを追加します
//
}


859:850
09/12/16 22:33:28
Form1.hの続き
protected:
/// <summary>
/// 使用中のリソースをすべてクリーンアップします。
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}

private:
/// <summary>
/// 必要なデザイナ変数です。
/// </summary>
System::ComponentModel::Container ^components;




860:デフォルトの名無しさん
09/12/16 22:35:58
Form1.h のつづき
#pragma region Windows Form Designer generated code
/// <summary>
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。
/// </summary>
void InitializeComponent(void)
{
this->components = gcnew System::ComponentModel::Container();
this->Size = System::Drawing::Size(300,300);
this->Text = L"Form1";
this->Padding = System::Windows::Forms::Padding(0);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
}
#pragma endregion
};
}

test.h の中身

#pragma once
public ref class MyToolStrip : System::Windows::Forms::ToolStrip { };

プロジェクトのプロパティでランタイムを共通言語ランタイム サポート (/clr)に変更して
コンパイル。ツールボックスの中にMyToolStripが現れるので、Form1へ貼り付け。

以上です。

861:デフォルトの名無しさん
09/12/17 10:41:25
だらだらコピペするんじゃなくて、再現する最小限のソースを作って貼るんだよ

862:デフォルトの名無しさん
09/12/17 12:30:50
>>861
最小限を貼っているようにしか見えないが。

863:デフォルトの名無しさん
09/12/17 13:33:13
//
//TODO: ここにコンストラクタ コードを追加します
//

864:デフォルトの名無しさん
09/12/17 13:34:51
つーかここでいう最小限は天順とtest.hを貼ればいいだけじゃないかw

865:デフォルトの名無しさん
09/12/17 13:35:17
天順→手順

866:デフォルトの名無しさん
09/12/17 13:37:25
何で貼るのかというと、レスをみた人が追試するためにはるんで
そもそも見る気失せるような書き方しちゃ手伝ってくれる人が減るだけだな。

867:デフォルトの名無しさん
09/12/17 13:39:45
>プロジェクトのプロパティでランタイムを共通言語ランタイム サポート (/clr)に変更して 
ソースが見当たらないが。IDEの制限だったような。pureじゃだめなん?

868:デフォルトの名無しさん
09/12/17 17:14:42
MyToolStripにpublicついてねぇぞ

869:デフォルトの名無しさん
09/12/17 17:42:56
>>868
refクラスではpublicを付けても付けなくてもpublic継承になる。
URLリンク(msdn.microsoft.com)

870:デフォルトの名無しさん
09/12/17 19:53:29
そもそもデザイナってILONLYじゃないアセンブリ読み込めたっけ

871:デフォルトの名無しさん
09/12/17 20:29:01
とりあえずソリューション内に別プロジェクトを作って、
そっちにMyToolStripを作って、メインプロジェクトから参照すれば、
/clr /clr:pure とどちらでもいけた。

872:デフォルトの名無しさん
09/12/23 02:57:12
>>850の問題とは関係ないかも知れないが、
自分もデザイナが見れないエラーに悩まされ、さっき解決したから載せとく。

(12).ToString();

上記のように、ToStringに直値指定するとデザイナが見れなくなる。
コンパイルも通り、実行もちゃんと反映されてるから、見つけるの苦労した

873:872
09/12/23 13:56:38
>>872に追加

InitializeComponent関数内でのToString直値がダメな原因だった。
そもそも、InitializeComponent関数はコードエディタで変更してはいけないらしい

InitializeComponent関数外でToString直値は正常に使える。

874:デフォルトの名無しさん
09/12/29 16:20:36
皆さんはC+/CLIでポインタを宣言する場合、
^や*を型の後ろにつけます?それとも変数名の頭につけます?

書籍等だと以下の形式が多い気がするのですが、
マネージとアンマネージで統一感がとれないような・・

[マネージ]
String^ hoge

[アンマネージ]
char *hoge


875:デフォルトの名無しさん
09/12/29 18:04:35
どっちも型名の直後につけるかな。
アンマネージでは変数の方につける人が多いみたいだけど、
ポインタ型っていう型名だから、変数の側につけるのには違和感があるんだ。

876:デフォルトの名無しさん
09/12/29 19:05:33
C#では構文上も型名の一部ということになってる
int *x, y, z;
と書くと全てポインタになる

877:デフォルトの名無しさん
09/12/29 21:16:52
>>875
>>876
C++/CLIだと型名の一部にはならないよね?
例えば以下のコードはコンパイルエラーとなる。

class Hoge{};

int main()
{
Hoge* x,y;
x= new Hoge;
y= new Hoge;//yがポインタとして認識されないため、コンパイルエラー
return 0;
}

CとかC++と同じ仕様なんだろうけど、
ポインタ型っていう考えでいくとなんでコンパイルエラーとなるのかが説明できない。
C#が特殊な気がする。

878:デフォルトの名無しさん
09/12/29 21:33:01
なんかCLIやってる人って可哀想だね

879:デフォルトの名無しさん
09/12/29 21:53:43
C/C++の構文がおかしいだけで意味上はポインタ型
不自然なのは誰の目にも明らかだからわざわざC#では変えたんだろ
どっちでもいいけどマネージとアンマネージで変えたりせずにどっちかに統一するべき

880:デフォルトの名無しさん
09/12/29 22:33:26
「つもり」は「意味」にならんだろ

881:デフォルトの名無しさん
09/12/29 23:18:54
ならんだろうね

882:デフォルトの名無しさん
09/12/30 00:11:42
あの記法でポインタを表そうとすると、
関数ポインタ型を表す場合、型の方に*をつけることは出来ないので、
変数の方に*をつけてポインタを表すというのは一定の合理性がある。

883:デフォルトの名無しさん
09/12/30 02:07:27
一定の合理性があるな。

884:デフォルトの名無しさん
10/01/02 10:56:36
CLIでcallocするとどうなるの?

885:デフォルトの名無しさん
10/01/02 11:50:26
普通にアンマネージヒープが割り当てられるだけ

886:デフォルトの名無しさん
10/01/03 18:49:18
当初VB.netで作った業務アプリをVC++/CLIに移植したのですが、
実行速度もメモリ使用量も違いがあるようには思えず、
WinXPだとVC++のランタイムが別途必要になった分、劣化したような気にすらなるのですが、
VC++/CLIの利点って、上達すれば業務アプリでもあるものなのでしょうか?

887:デフォルトの名無しさん
10/01/03 19:19:16
ない
既存のアンマネージコードをマネージコードと混ぜるためだけに仕方なく使う言語
その場合も使用範囲は最小限に留めて,できるだけVBやC#で書くようにするのが正しい

888:デフォルトの名無しさん
10/01/03 20:26:51
gcnewをなめるなよ

889:デフォルトの名無しさん
10/01/03 20:49:08
MS自身ですら避けてるからな
マネージからアンマネージ→DllImport
アンマネージからマネージ→CLRのホスティング

890:デフォルトの名無しさん
10/01/03 22:27:46
XNAくらいだっけ、MS製で使ってるの

891:デフォルトの名無しさん
10/01/06 21:01:42
CLI 使ってる時点で速さが変わらないのは当たり前
アンマネージドコードを利用しないと速くなる訳が無い

892:デフォルトの名無しさん
10/01/06 22:16:08
新規にアンマネージコード書くなら普通のネイティブなDLLとして作ってC#からDllImportする形の方が扱いやすい

893:デフォルトの名無しさん
10/01/07 20:22:39
XNAってなんで早く動くの?

894:デフォルトの名無しさん
10/01/07 21:01:54
ゲームってDirect3Dに描画命令を送ってからの内部の処理が重くてボトルネックになるので
C++/CLIを挟もうがゲームロジックがマネージコードで書かれてようがあんまりパフォーマンスに影響しない

895:デフォルトの名無しさん
10/01/15 20:33:57
ネイティブのアプリケーションがプラグインに飛ばしてくるコールバックを拾って、
それをC#に渡して処理するアプリケーションを書きたいのですが、
その辺のノウハウについてまとまっている情報源をご存知の方はいませんか?

896:デフォルトの名無しさん
10/01/15 20:47:27
イベントかインターフェイス経由でC#にそのまま流せばいいだけでしょ
全く悩むところなんかない

897:デフォルトの名無しさん
10/01/15 21:00:14
>>896
C++/CLIで書いたコードって、普通にやるとマネージコードにコンパイルされると
思っていたのですが、ネイティブから呼ばれても大丈夫なのでしょうか。

898:デフォルトの名無しさん
10/01/15 21:05:35
/clr なら相互に呼び出し可
/clr:pure の場合、マネージドコードからネイティブ方向の呼び出しは可
/clr:safe の場合、不可、ただしP/Invokeは可能。

Win32APIのコールバックを直接C#で処理したいなら、
特殊なものでなければ、P/Invoke+Delegateで対応可能。

899:デフォルトの名無しさん
10/01/15 21:11:21
最悪COM経由でどうとでもなる

900:デフォルトの名無しさん
10/01/15 21:20:41
>>898
分かりやすい解説感謝します。
そういうことなら、普通にアプリ指定のコールバック関数を定義して、
そこからC#のコードを呼べばよさそうですね。ありがとうございます。

901:デフォルトの名無しさん
10/01/15 23:01:30
教えてください。

まず、VC2003 で作った一部マネージコードの混じったアンマネージの .lib ファイルがあります。
これを(ちょっと事情があって) VC2003 でアンマネージの .dll にくるみました。
で、これを(さらに事情があって) VC2008 の C++/CLI でマネージの .dll に
DllImport を利用してラッピングしようとしています。

ここで、ライブラリとして公開する関数はいくつかあるのですが、その中にパラメータとして
構造体を参照形式で持つモノがあります。
構造体の中には std::string で定義した要素を持つモノもあるのですが、これを先のアンマネージの
.lib の関数内で参照したり変更したりするとアクセスバイオレーションで不正終了することがあります。
同じ構造体内の int 型などの要素の値を参照/変更しても変な値が入ることがあります。
そこで、この構造体の std::string 型の要素を char[] 型に変更して試したところ、特に問題なく期待通りの動作をしました。
マネージ dll を介さずに、アンマネージの .dll を使用する分には元のままでも問題なさそうです。

この原因ってなんでしょうか。
また、回避方法があれば教えていただけないでしょうか。

902:デフォルトの名無しさん
10/01/15 23:03:11
ゲームでCOM経由はどうなんだろう
DllImport、P/Invoke+Delegate とは違うんだよね
どんな時に使うんだろう…どう使い分けるのかの時点で悩みそうだ…

903:デフォルトの名無しさん
10/01/15 23:18:09
>>901
そんな使い方するのがおかしい。
C++/CLIでアンマネージドとマネージドを混ぜたら、あとはマネージド側から使うだけ。

904:デフォルトの名無しさん
10/01/15 23:24:50
>>901
真っ先に思い浮かぶのは、メモリ確保周りの問題。
2つのDLLでstd::stringが同じメモリ確保ルーチンを使うようにしてみたらどうなる?
例えば、両方でグローバルなnew/delete演算子関数を定義するとか。
#include <new>
void* operator new(std::size_t n)
{
if (void* p = HeapAlloc(GetProcessHeap(), 0, n))
return p;
else
throw new std::bad_alloc();
}

void operator delete(void* p)
{
if (p != 0)
HeapFree(GetProcessHeap(), 0, p);
}
std::stringに対して自前のアロケータを指定するというのでもいい。

905:デフォルトの名無しさん
10/01/15 23:42:18
VC2003ってことはManaged C++か

906:デフォルトの名無しさん
10/01/15 23:54:56
>>901
C++/CLI以前の問題じゃないか、それ

基本的にDLL境界をまたいで、FILE*のようなCランタイムオブジェクトや
malloc()/newで確保されたメモリ渡すときは要注意
Aで確保されたメモリをBで開放するときは、モジュールAとBが同一の
ランタイムにダイナミックリンクしてないと即終了
C++のstd::stringなんぞをインタフェースに使ってたらそういうことは
当たり前に起きる

>>904の指摘はそれを前提にしている訳だが、
C++標準ライブラリクラスは、そもそも実装の大半がヘッダにあり、
バージョンが違えばそのバイナリ互換性すら怪しい
俺はそもそも設計として、C++標準ライブラリクラスをDLLインタフェースに
使うことは全くオススメしない
設計を見直すべき

907:デフォルトの名無しさん
10/01/16 00:13:38
>>904
URLリンク(developer.apple.com)
URLリンク(ameblo.jp)

調べてみた。部分的なら書き換えおkだけど
標準部分の書きかえはそれなりに茨の道な気がする…

908:デフォルトの名無しさん
10/01/16 16:48:20
C++/CLIも.NET総合もくだすれが発見出来ないので、おそるおそるここで聞かせて頂きます。

DLLを制作しているのですが、DLL中からフォームを呼び出すレベルで詰まっています。
DLL自体は動的に外部の別のDLLから呼び出され、初期化関数が走らされる感じで、

IDEからWindowsフォーム(CLR)を追加し、フォームを何も弄らない状態で
DLLの初期化関数中で(gcnew hoge::hogeForm())->Show();
しているのですが、Showの呼び出し中に固まってしまいます。
メッセージループが存在しないせいかと思い、Application::Run();してから
Showしても同様です。

通常のexeを作成し、メインウィンドウのインスタンスをもう一つ同様にShowしようとしても
同じく死んだので、何か初歩的なレベルでミスしているのだと思うのですが、
エスパーしていただけないでしょうか……。


909:デフォルトの名無しさん
10/01/16 16:54:28
Application::Run(gcnew hoge::hogeForm());

910:>>901
10/01/16 18:05:57
>>903-907 のみなさま、ありがとうございます。

特に >>906 さん。なんとなくわかってはいたのですが、言葉できっちり表現がされていて助かります。
>>904 さんの方法も試した上で、週明けに改めて説明を行って対応方法を変更する方向で動きます。

911:デフォルトの名無しさん
10/01/16 19:44:08
>>908
(gcnew hoge::hogeForm())->Show(); じゃフォームのハンドルを押さえているヤツが居ないな

912:デフォルトの名無しさん
10/01/16 22:48:45
Formは表示中GCの対象外になるようになってる

913:908
10/01/17 04:44:50
>>909
>>911-912
どうもありがとうございます。
Application::Run(gcnew hoge::hogeForm());も試して見ましたが、同様にそこで処理が止まります。
(次の行でデバッグ用の出力を入れていますが、出力されません)

ネイティヴ関数の状態から(CLRでない空のプロジェクトにグローバル関数を置いた状態から)、
/CLRを追加し、Windowsフォーム(CLI)の追加、
グローバル関数を記述したcppからのmscorlib.dllやフォームのヘッダの参照、
Application::Run(gcnew hoge::hogeForm());と、やっていることはこれだけで、
以下のような感じです。

#include <windows.h>
#using <mscorlib.dll>
#include "hogeForm.h"
int __stdcall Init() {
Application::Run(gcnew hoge::hogeForm());
}

ManagedとUnmanagedの区分け等、何か気を遣うところがあるでしょうか。


914:デフォルトの名無しさん
10/01/17 05:09:13
>>913
Init()を呼び出す。
フォームが表示される。
フォームを表示したままinit()が終了して呼び出し元に戻ってくる。
というのを期待しているとかしてないよね?


915:908
10/01/17 05:15:53
>>914
フォームが表示されることは期待しています。
上のコードでは、フォームを終了しない限り、処理が呼び出し元に返ってくることは期待してません。


916:デフォルトの名無しさん
10/01/17 05:18:14
とりあえずこれで動いてる
// testd8.cpp managed
#using <System.dll>
#using <System.Windows.Forms.dll>
using namespace System;
using namespace System::Windows::Forms;
void Init() {
  Application::Run(gcnew Form);
}
// testd9.cpp native
void Init();
int main() {
  Init();
  return 0;
}

cl /clr /c  testd8.cpp
cl /MD testd9.cpp testd8.obj


917:908
10/01/17 18:35:12
>>916
同等の物を書いてみましたが、確かに動作しています。
呼び出し方法やら何やら、片っ端から確認していって、原因を特定しようと思います。
どうもありがとうございます。


918:デフォルトの名無しさん
10/01/17 22:05:10
汎用的なDLLでいきなりApplication::Runとかされたらヤだな

919:デフォルトの名無しさん
10/01/21 22:57:19
質問ですが、
タイトルバーがなく3Dの縁があるフォームを作るには
どうすればいいのでしょうか。
環境はVC++2008です。
フォームのプロパティ設定の中には見つかりませんでした。


920:デフォルトの名無しさん
10/01/22 00:10:35
C# タイトルバー 消す
とかでググれば一発
調べても分からない場合でもそういう質問はC#かVBスレでしたほうがいい

921:デフォルトの名無しさん
10/01/22 21:52:51
>>920
なるほど、.NETなら共通なんですね。
わかりました、ありがとうございます!


922:デフォルトの名無しさん
10/01/23 11:53:50
Visual Stuidion C++ 2008での書き方を教えて。

フォームクラスだと、イベント関数とかすべてヘッダの方に生成されるけど、
独自メソッドもすべてヘッダーの方に書くものなの?
それともプライベート関数はcppの方に書くとかルールがあるの?


923:デフォルトの名無しさん
10/01/23 16:01:29
俺はヘッダは宣言のみにして、ソースファイルに定義。プロパティも同じ。
全部ヘッダに書いて、cpp削除でもいいんじゃね?w

924:デフォルトの名無しさん
10/01/23 20:14:29
自分もそうかな。プロパティはヘッダに書いちゃうこともある。
C# とかは分かれてないからどっちでもいいと言えばいいんだと思うけど、C/C++ の伝統がそうさせる。w

925:デフォルトの名無しさん
10/01/24 16:24:16
.NET言語って全部コンパイル速いからな~、ヘッダに書いといて無駄なコンパイル発生しても
ほとんど気にならないレベル

926:デフォルトの名無しさん
10/01/26 00:04:55
temp_buf[TEMP_BUF_SIZE], temp_buf2[TEMP_BUF_SIZE]は'\0'で初期化されてます。
文字列がtem_bufに格納され、その中から"search"を探索し、文字列が見つかれば
そのsearchのs以降の文字をtemp_buf2にコピーしようとしています。
が、実行すると暴走してしまいます。
*pの使い方がおかしいような気もするんですが、
原因が分かりません。
環境はgccですが手元にpcが無いので詳細は分かりません。
もし必要でしたら調べてきます。ごめんなさい。

char com[] = "search";
char *p = strstr(temp_buf,com);
if( *p != NULL ){
if( sizeof(temp_buf2) - &(temp_buf[TEMP_BUF_SIZE-1])-&(*p)+1 < 0){
fprintf( stderr, " buffer overflow 1\n" );
exit(-1);
}
strcat( temp_buf2, p );
printf("%s",temp_buf2);
 }

よろしくお願い致します。


927:デフォルトの名無しさん
10/01/26 00:13:34
>>926
>>1

928:デフォルトの名無しさん
10/01/26 00:23:02
スレチですね
失礼します

929:デフォルトの名無しさん
10/01/26 00:26:06
>>928 は
>>926
のことです

930:デフォルトの名無しさん
10/01/26 22:01:38
VC++ 2008 ExpressEdition で Form::Controlクラスを継承した独自コントロールクラスに
枠をつけるにはどうすればいいのでしょうか?
プロパティ設定には境界線の項目がありません。
それらしきメソッドも見当たりません。誰か知っていたら教えてください。

931:デフォルトの名無しさん
10/01/26 22:06:43
>>930
ほい。
URLリンク(uchukamen.com)

932:デフォルトの名無しさん
10/01/26 22:14:16
>>930
VisualStyleRenderer使って自前で描画する
プロパティも自分で実装する
あと>>920の3行目

933:デフォルトの名無しさん
10/01/26 22:19:28
要するに、
コモンコントロールのそれぞれは自前で描画していたんですね。。
良く分かりました、ありがとうございます。

934:デフォルトの名無しさん
10/01/26 22:23:25
>>933
Windowsで動作するほぼ全てのウィジェットレンダラーは
Win32GDIをまとめ直したものに過ぎないんだが、
最近の人はWin32APIで直接アプリを作ったりする経験がないから自前で描画する、という感覚がつかみにくいのかもしれんねぇ。

それはそうと、コントロール描画くらいならC#で実装した方が簡単だよ。

935:デフォルトの名無しさん
10/01/26 22:30:26
>>934
動作のコアとなる部分がC++で作ってあって、DLLとしてまとめてあるんだけど、
GUI側をC#で作るとなると、呼び出すのに定義作り直すのがめんどうで、
どうしてもこの言語に手を出さざるをえないのよね。

936:デフォルトの名無しさん
10/01/26 22:32:56
>>935
ええー。今時、WindowsでGUIを書くのにC++を使うなんて、マゾとしか思えん。
逆ならわかるがねぇ。
GUIをC#で書いてモデルや下回りをC++でってなら。

937:932
10/01/26 22:36:49
すまん枠描くのはControlPaintだった
よっぽど深い相互運用しない限りはexport/DllImportの手間を差し引いてもC#の方が楽だし
安全だし取り回ししやすいよ

938:935
10/01/26 22:44:13
>>936-937
むう、再検討します。


939:デフォルトの名無しさん
10/01/26 22:58:32
いわゆる普通の ウィンドウ枠は WS_BORDER だぞと。
普通は CreateParams オーバーライドして Style プロパティに
WS_BORDER のビットフラグ立てたのにするだけ。
3D 枠とかも基本は一緒な

940:デフォルトの名無しさん
10/01/26 23:04:22
いやWindowsネイティブのコントロールに対応しない独自描画のカスタムコントロールの場合は
枠も自分で描くべき
標準のコントロールもそうなってる

941:デフォルトの名無しさん
10/01/28 10:27:29
そもそもコモンコントロールだってただの画像だしな

942:デフォルトの名無しさん
10/01/29 00:20:52
C++/CLI と C# embedded C++ どっちがいい?

943:デフォルトの名無しさん
10/01/29 00:48:20
3択な上に比較対象がおかしい。

944:デフォルトの名無しさん
10/01/29 02:04:59
何がしたいのかも判らんのに「どれがいい」も糞もないけどな。
WM (CE) の話で C++/CLI or C# or eVC++ のどれか、っていうなら
…いや、やっぱり好きにしろとしか言えないw

945:デフォルトの名無しさん
10/01/29 02:46:25
(C++ in C#) の意味では?

946:デフォルトの名無しさん
10/01/29 09:39:46
>>942-943
ワロw

947:デフォルトの名無しさん
10/01/31 03:31:10
これからはC++0x/CLIの時代だろ

948:デフォルトの名無しさん
10/01/31 05:14:01
敵はObjective-C++0xだな

949:デフォルトの名無しさん
10/01/31 06:53:39
今までC++とC#ばかりいじくっていたが、Google様にお伺いを立てると
実行速度は

C++ > C++/CLI > C#, VB.NET らしい

C++/CLIの方が効率よく高速なMSILに変換される仕組みでもあるのかな?

950:デフォルトの名無しさん
10/01/31 11:12:50
無いし実際同じ

951:デフォルトの名無しさん
10/01/31 11:22:21
C++/CLI はネイティブコードで書いた部分の実行速度が速いからとかじゃ?

952:デフォルトの名無しさん
10/01/31 11:38:51
ボックス化された値型とかトラッキング参照とか駆使して低レベルな最適化をやれば速くなるかもしれないけど
JITのバージョンアップであっさり逆転したりしそうだ

953:デフォルトの名無しさん
10/01/31 22:47:30
検証に使用したコードがないと話にならんだろ。

954:デフォルトの名無しさん
10/01/31 22:51:54
C#よりもC++/CLIの方ができることの制限が少ないから、速いコードを書くこと余地は大きいだろうね。
C++はUnsafeだから、こういうのを単純に比較しても意味ないと思うんだけどな。

955:デフォルトの名無しさん
10/01/31 23:03:35
一般に将来的な最適化の妨げになるしなあ

956:デフォルトの名無しさん
10/02/01 03:06:48
C++/CLIの速さはこの2つを足して2で割ったところとしているんでしょ。
マネージ部分の速さ = C#, VB.NET
ネイティブ部分の速さ = C++

957:デフォルトの名無しさん
10/02/01 09:17:41
まあアンマネージだけで書いたらC++もC++/CLIも変わらんわな
マネージだけで書いたらC++/CLIもC#も変わらんわな

測ってないけど

958:デフォルトの名無しさん
10/02/01 10:42:19
くだすれ落ちているのでここで失礼します。

unmanagedなバイト配列(unsigned char* byteArray, int len)を
managedな配列(array<Byte>)に変換したいと考えています。
とりあえずインデクサをつけて一個一個代入していったり、
Addしてみたりしたのですが、随分と処理に時間を喰ってしまいます。
そこまで速度に神経質なプログラムでも無いのですが、
もっとスマートに配列を変換する方法は無いものでしょうか。


959:デフォルトの名無しさん
10/02/01 11:29:42
Marshal.Copy(IntPtr, byte[], int, int) とか。

960:958
10/02/01 12:04:10
>>959
Marshal探せば良かったんですね。
Managedメモリを固定して確保してからmemcopyとか、明後日の方向に向かって努力していました……。
どうもありがとうございました。


961:デフォルトの名無しさん
10/02/02 03:10:27
C++/CLIは/clr /clr:pureでは常にunsafeであり、
Cタイプの配列を使った場合のパフォーマンスが良い。1~2割程度。
C++/CLIの暗黙のP/InvokeはSuppressUnmanagedCodeSecurityAttributeがデフォルトでオンなので、
C#のP/Invokeに対してパフォーマンスが良い。2~3倍程度。
C#のP/InvokeにSuppressUnmanagedCodeSecurityAttributeを追加するとその差はなくなる。
またC++/CLIのリンク時に/CLRUNMANAGEDCODECHECKを付けると、
この属性がオフになるためパフォーマンスはC#と変わらなくなる。


962:デフォルトの名無しさん
10/02/02 21:49:51
C#でも一応スタックに配列取ったりマネージ配列やアンマネージ配列にポインタでアクセスしたりできるよ

963:デフォルトの名無しさん
10/02/02 22:10:43
マネージドで書いとけばいいのにやたらアンマネージド呼び出して
結果マーシャリングコストばっかりかかってパフォーマンス悪化とか、ありそうな話


最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch