1 :
デフォルトの名無しさん :
2006/03/12(日) 15:15:10
2 :
デフォルトの名無しさん :2006/03/12(日) 15:15:54
スレたて、ありがとうです早速ですがよろしくお願いします UInt64 hogeを入力したら、16進数変換して、文字変数tmpを返す処理を よく使う処理なので関数化したいのですが、変数のスコープで調べて見ましたが 明確な解決方法がみつかりませんよろしくオナガイシマス 関数 String^hex_convert(UInt64 hoge) { wchar_t foo[16]; memset(foo,0,16*sizeof(wchar_t)); _i64tow_s(hoge,foo,16,16); String^tmp=gcnew String(foo);//この部分では変数tmpはString型として定義されている return tmp += " (System::String)"; } 本体側のソース UInt64 hoge =Convert::ToUInt64(textBox1->Text,16); { hex_convert(hoge); textBox2->Text = tmp;//変数tmpは未定義と怒られる }
本体側で呼んだhex_convert()の返り値をTextに入れろと。
>>4 それにしてもなめられたコードをもらったもんだな。
String^ hex_convert(UInt64 hoge)
{
return hoge.ToString("X") + " (System::String)";
}
そしてそれを使う方。
{
UInt64 hoge = Convert::ToUInt64(textBox1->Text, 16);
textBox2->Text = hex_convert(hoge);
}
しかしこれでは何が駄目なのか。変換してまた変換するのは無駄だと思う。
こうすればtextBox1->Textが十六進法の文字列としてとして正当かどうか調べたければ、
こうすれば十分。Convert::ToUInt64が変換できなければ冷害を投げてくれる。
{
(void)Convert::ToUInt64(textBox1->Text, 16);
textBox2->Text = textBox1->Text;
}
>>6 さんどうもです
変換部分は関数化しなくても良い理由はよくわかりました
ただ関数化したかった理由として書込み部分で、基数変換があったからです
//buttun2(Open File)で開いたファイルを読込み(ARG_2)、変数i(Dec→Hex)と結合し変数の数だけファイルを作る
private:
System::Void button4_Click(System::Object^ sender, System::EventArgs^ e){
for(UInt64 i = h_start;i < h_end; i ++)
{
String^hoge = Convert::ToString(i);
wchar_t foo[16];
memset(foo, 0, 16*sizeof(wchar_t));
_i64tow_s (i,foo,16,16);
String ^tmp = gcnew String(foo);
StreamWriter^ sw = gcnew StreamWriter ("d:\\hoge\\hoge_"+hoge+ ".txt");
sw->Write(tmp + System::Environment::NewLine+ARG_2);
sw->Close();
}
String^hoge = Convert::ToString(i->hoge,16);
MSDNを読んだらiからhogeへ基数変換できると思ったのですが、
: error C2227: '->hoge' : 左側がクラス、構造体、共用体、ジェネリック型へのポインタではありません。
MSDNではジェネリック型のユーザーは、制約を満たさない型引数を置き換えることはできません。
多分この部分でエラーが出ていると思うのですがこれ以上深く原因を掘り下げれません。解説お願い出来ないでしょうか。
i->hoge て。いつから UInt64 に hoge なんてメンバが。 アロー演算子の意味分かってるか?
>>9 さん
そうなんですよね構造体のメンバー変数参照するわけだから、
変数を代入する振る舞いではないですよね
すみませんでした、自己解決しました 自分のコードの中に答えがあるとは、 相変わらず何やってんだか
>>7 TryParseは基数を指定できるように見えないのだが。
>>8 StreamWriterは自動変数でいいと思う。
>>12 NumberStyles.HexNumber
エンコードしたい時 StreamReader、StreamWriter 両方にくっつけないと、だめな仕様みたいですね 当たり前と言えば当たり前のことなんだが ヘッダー辺りに、ちょろちょろっと、宣言して 「このプログラムはshift-jisなんだぞ、いいな下々のものよ」ってな 感じににはできないわけ?
意味が分からん
CLI の内部コードはユニコードだから、駄目だろ
たとえばshift-jisのファイルを読み込んで、shift-jisで書き出すときに System::IO::StreamReader(openFileDialog1->FileName,System::Text::Encoding::GetEncoding("Shift_JIS")); って読み込んで sw->Write(hoge,System::Text::Encoding::GetEncoding("Shift_JIS")); こんな感じで書き出さない? これだと読む時も書く時も、Text::Encoding::GetEncoding("Shift_JIS")); が必要なんだけど、これをもっと簡単にする方法って無いのかなってこと
initonlyなクラス変数にでもしとけ
System::Text::Encoding::Default でいいだろ
22 :
デフォルトの名無しさん :2006/03/14(火) 23:39:53
using namespaceってどこまで深く書くのが普通なんですか?
自分が楽に書けて、他と名称衝突しない程度
関数内だったら原則いけるとこまでやる。 外なら短い別名付けることを考える。
>>23 衝突しそうだったら alias しちゃうのも手だよな。
26 :
デフォルトの名無しさん :2006/03/15(水) 00:36:54
どうも。もう一つ質問。 gcnewしたオブジェクトは明示的にdeleteしなくていいみたいだけど、 gcnewってnewより遅いとかデメリットありますか? これから新しく書くコードは全部gcnew使った方が良い?
ネイティブとマネージを単純に比較するわけにはいかんだろ
ネイティブしかサポートしない大多数のコンパイラへの 移植性を考えなければ、マネージドで書いておくのがいいんじゃね? とはいえ漏れはコア部分は全部ネイティブで書いて、 GUIの部分だけマネージドで書いてるけど。 GUIのところだけネイティブから Application::Run(gcnew Form1); みたくやってそっちはマネージにお任せ、って感じで。
ありがとうです。 今日初めてCLIで"Hello, World"しました。 明日もよろしく。
30 :
デフォルトの名無しさん :2006/03/15(水) 01:58:52
>>26 GCに任せないすぐDisposeしなきゃいけない場合は
deleteする必要あるよ。
31 :
デフォルトの名無しさん :2006/03/15(水) 02:52:29
ぬるぽ
32 :
デフォルトの名無しさん :2006/03/15(水) 02:56:11
従来のC/C++で void func(void **pp) { *pp = new Object; } のように関数の引数で新しいインスタンスを返すような実装はどのようにやればいいのでしょうか? void func2(ArrayList ^*pp) { *pp = gcnew ArrayList } のような関数で試してみたらfunc2呼び出し部分でコンパイルエラーになってしまいました・・・
試してないけど void func(ArrayList^% pr) { pr = gcnew ArrayList(); }
>>33 それだとポインタへの参照だから、void func(void*& rp)が対応すると思う。
正確さを期するならこうだと思う
void f(cli::interior_ptr<ArrayList^> pp)
{
*pp = gcnew ArrayList();
}
ただこうする必要性は全く無いから実用上は33の方法で十分。
ちなみに外に見せるものならOut属性を付ければC#などからout引数として認識される。
void func([System::Runtime::InteropServices::Out] ArrayList^% pr)
35 :
デフォルトの名無しさん :2006/03/15(水) 09:34:05
テストの質問にこんなのがありました。どう答えればいいのでしょうか? 質問: C++でvirtual constructorが無いのは何故か?
37 :
デフォルトの名無しさん :2006/03/15(水) 11:34:32
java applete Applete java awt.Grahics { java class(strings arg[]) { "谷川浩司名人”; System.out.printlin.; } }
System.Net.Mail機能を使う場合、 using namespace System; という宣言以外、他に必要ありませんか?
>>38 using namespace System::Net::Mail;
毎回ネームスペースを修飾するなら何もいらん。
たいていのプロバイダは pop before SMTP なんじゃね?
このMail機能はWindows ServerのSMTPサービスを経由してプロバイダのSMTPに投げるような思想じゃないだろうか。 SmtpClient.Credentialsの説明を読んでたらそんな気がしてきた。普通にメーラーを作るのには向いてなさそうだ。
POP3 クラスも無いのに何を今更。
40ですが PerlやPHPなら簡単に実装出来る機能なのになぁ・・・
ならperlやPHPで実装すればいいよ
漏れのコードネームUzbekistan開発プロジェクトはスタートにして終焉か・・・ PerlやPHPじゃぁGUI作れねーんだよな
49 :
デフォルトの名無しさん :2006/03/15(水) 23:44:13
>>33 >>34 ありがとうございます、試してみます
正確に**を再現しようとするとcli::interior_ptr<ArrayList^>になるのですね
勉強になりました
50 :
デフォルトの名無しさん :2006/03/15(水) 23:50:32
ギコナビつかってんだけど このスレノートンでUnix.Penguinとか言うウイルスに認定される・・・
>>51 thx
勝手にノートンに消されちゃうのつらいなあ
そのための C++/CLI だぜ
>>53 System.IO.Compression.GZipStream2.0で追加だから使えるよ。
Microsoft.VisualBasicやらMicrosoft.JSharpやらのは使えても使わないほうがいいけど、
System系だから安心して使ってよし。
> Microsoft.VisualBasicやらMicrosoft.JSharpやらのは使えても使わないほうがいいけど、 C++/CLIなんてのに手を出すのなら使えるものは親でも使え、で良いと思うけど。
Microsoft.VisualBasicは.NETのランタイムを入れいれば一緒にインストールされるが、 J#のは別にインストールしなきゃいかんからね。
J# はなぁ、ライブラリがかなり古い&不完全だよね? ライセンスの関係上仕方ないんだろうけど、 正直、使いみちが無い・・・・・ 手持ちの Java のコードも結構有って、 VS でいじりたいんだけどなぁ。
JavaからC#にコンバートすれば?
J#スレがかつてあった。1.1.4互換じゃ使えねぇって結論だった。 VS2005 Std を買ってきたがJ#だけインストールからはずしてやった。
C++から、C#もJavaを経験せずにC++/CLIに移行したい人のための 解説サイトってないですか? 比較の対象がC#ばっかりで、C#知らないと全然分からない。
C++知ってればC#のコードぐらい読めるだろ 読めなかったらプログラマ辞めちまえ
関数呼び出したら : error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません 怒られますどうしてデツカ sGoodDate( int Year, int Month, int Day ) { return ((Month>=1)&&(Month<=12)&&(Day>=1)&&(Day<=DaysInMonth(Year,Month))); }
>>64 返値の型が指定されてないから。
sGoodDate( int Year, int Month, int Day )
↓
int sGoodDate( int Year, int Month, int Day )
intじゃなくてboolのようだが
>>65 それはやりました
そうすると今度は、
error C3861: 'DaysInMonth': 識別子が見つかりませんでした
になります
もういいや
>>67 そもそもC/C++できるのか?
sGoodDateよりも前にDaysInMonthの宣言はあるのか?
こうですが?#include "stdafx.h" #include <iostream> using namespace std; int IsGoodDate( int Year, int Month, int Day ) { return ((Month>=1)&&(Month<=12)&&(Day>=1)&&(Day<=DaysInMonth(Year,Month))); }//IsGoodDate int DaysInMonth( int nYear, int nMonth ) { const int nDaysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if ( ( nMonth < 1 ) || ( 12 < nMonth ) ) return 0; if ( (2 == nMonth) && IsLeapYear(nYear) ) return 29; return nDaysInMonth[nMonth-1]; }//DaysInMonth int main (void) { int Year=0, Month=0, Day=0; cin >> Year >>Month >> Day; cout << ((Month>=1)&&(Month<=12)&&(Day>=1)&&(Day<=DaysInMonth(Year,Month))); return(0) }
IsLeapYearはどこだ IsGoodDateはDaysInMonthを知らないだろ ってかこれはC++/CLIじゃねぇ
内容からすると学校の宿題かな
>70 まぁ、Cから勉強して出直してこいってこったな 使用する前に宣言されていないと、使えねぇんだよ
1にCやC++は別スレだと書いた方がいいと思う。
76 :
http://www.vector.co.jp/soft/win95/util/se072729.html :2006/03/18(土) 19:59:19
TextSS のWindowsXP(Professional)64bit化おながいします もしくは64bitにネイティブ対応したテキスト置換ソフトありますか?
C#で System.Web.Mail.SmtpMail.SmtpServer = "mail.hoge.co.jp"; っていうコード C/C++的にはどう書いたらイイデツカ
>>77 静的メンバと名前空間へのアクセスには :: スコープ解決演算子。
System::Web::Mail::SmtpMail::SmtpServer = "mail.hoge.co.jp";
^漏れも夕べそれやったんだけど 結果は hoge.cpp .\hoge.cpp(4) : error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません .\hoge.cpp(5) : error C3083: 'Mail': '::' の左側のシンボルには、型を指定しなければなりません .\hoge.cpp(5) : error C3083: 'SmtpMail': '::' の左側のシンボルには、型を指定しなければなりません .\hoge.cpp(5) : error C2039: 'SmtpServer' : 'System::Web' のメンバではありません。 .\hoge.cpp(5) : error C2065: 'SmtpServer' : 定義されていない識別子です。 でした orz
>>79 > .\hoge.cpp(4) : error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません
関数の返値が未定義
> .\hoge.cpp(5) : error C3083: 'Mail': '::' の左側のシンボルには、型を指定しなければなりません
> .\hoge.cpp(5) : error C3083: 'SmtpMail': '::' の左側のシンボルには、型を指定しなければなりません
> .\hoge.cpp(5) : error C2039: 'SmtpServer' : 'System::Web' のメンバではありません。
> .\hoge.cpp(5) : error C2065: 'SmtpServer' : 定義されていない識別子です。
DLLの参照不足
こう using namespace System.Web.Mail ?
>81 プロジェクトのDLL参照で追加
どのDLLを追加したらええの?
おまいが使っている名前空間のアセンブリ
System WebMilっていうDLLがあるかと思ったら System Webなんだね やっとメールが送れたお
MSDNぐらい見ろ
コンソールでは、コンパイルもできてメールも送れるんだけど
GUIにしたら、コンパイルはできても、例外エラーがでてメール送れないんだよね
なんでだろう??
The server rejected one or more recipient address.
The server response was:550 5.11<System Windows.Forms.TextBox>///User
GUIのプログラム
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
String^ Mailsever = "mail.hoge.ne.jp";
String^ From = "
[email protected] ";
String^ To;
String^ Title;
String^ Message;
To = Convert::ToString(textBox1);
Title = Convert::ToString(textBox2);
Message = System::Convert::ToString(textBox3);
System::Web::Mail::SmtpMail::SmtpServer = Mailsever;
System::Web::Mail::SmtpMail::Send(
From,
To,
Title,
Message);
return;
}
取りあえず System::Net::Mail 名前空間使った実装に置き換えてみたらどうだ。
今、今、
To = Convert::ToString(textBox1);
を
String^ To =
[email protected] にしたら、成功したけど
TitleやMessageが入力したものに余分なものがくっついている
どうやらそれが原因のようです
Messageにaaaといれたら
System.Windows.Forms.TextBox, Text: aaa
なんだよね、To = Convert::ToString(textBox1);
これでいいよね?
t聞いてみる。
×Messageにaaaといれたら ○textBox3にaaaと入力 です
多分文字列エンコーディングの問題だな その辺かなり最低限しか実装してなかったはず どっかで見たけど結論は「Socket 使って自前でプロトコル喋れ」だった
93 :
デフォルトの名無しさん :2006/03/21(火) 18:28:32
Visual C++ 2005 Express Editionを使っています。ネイティブで コンソールアプリケーションとして作成したソフトをベースとして、メイン関数 のみをwindowsフォームに置き換えました。/clrpureオプションでコンパイル する分にはネイティブの時より2割遅い程度だったのですが、/clrとして windowsフォーム以外のソースのincludeの下に#pragma unmanagedを入れると 速くなるどころか1/10程度の速度になってしまいました。何とか元の 速度で動かす方法はないでしょうか。これだけでは情報が不足しているかも しれませんが、何かアドバイスがあればお願いします。
これが抜けていた ->Text できたお、まだまだ不慣れやなC++の書き方
>>93 マネージドとアンマネージドの切り替えには時間が掛かる。
だからフォーム以外全部マネージドでは頻繁に、
マネージドとアンマネージドの切り替えが起こるので遅くなって当然。
System::Web::Mailの実装できたので System::Net::Mail使って見ようと思ってMSDN見てるけど 使い方は大体同じ感じだけど messageの使い方がミソかな? SubjectやBodyをコピーコンストラクターで使うみたいなんだけど エンコードもきっちり決まってんのかな?? コンパイラ君が素直に言うこと聞いてくれないお なんか制限が多い感じがするNE
97 :
デフォルトの名無しさん :2006/03/21(火) 23:03:58
93です。 今、作っているのは思考ゲームで、思考ルーチンは全部アンマネージドの つもりです。その間はGUIは動かないので、マネージドとの切り替えは ないものと考えています。ただし、アンマネージド指定をしたソースの 出力コードを見てみるとコンストラクタ等一部がMSILになってしまって おり、これが響いているかもしれません。 が
GUIが動くかどうかじゃなくてコンテキストの問題。 例えばマネージドの関数内でアンマネージドの関数何度も呼べばその度にマーシャリングが発生してパフォーマンスが落ちる。
99 :
デフォルトの名無しさん :2006/03/21(火) 23:28:16
93です。一部簡略化していますが、下記のような構成になっています。 マネージド⇔アンマネージドの切り替えは本来ほとんど必要ないと 思うのですが、避ける方法はないでしょうか。 ------Form1.h内容----- (自動生成されたものに追加) #include "myclass.h" マウスのクリックにより、MyClassのインスタンスを作成し、 そのメンバー関数think()を呼び出す。 ------myclass.h内容---- クラスMyClassの宣言 ------mycalss.cpp内容 #include "myclass.h" #pragma unmanaged クラスMyClassのメンバー関数の定義 メンバー関数think()からは直接・間接的にもMyClassのメンバー関数 しか呼ばない。また、その処理時間は秒単位でかかる。
>>99 ならばmyclass.h内のMyClassの宣言とForm1.h内のthinkをアンマネージドに放り込んだらどうかと思う。
101 :
デフォルトの名無しさん :2006/03/23(木) 14:57:45
99です。 下記二点を見直し、コンソールアプリケーションと同等のパフォーマンスになりました。 ありがとうございます。 (1) MyClassの宣言をアンマネージドにした。 #pragma unmanagedを#include"myclass.h"の前に持って来ました。当初こうしても まったくunmanagedにならなかったのですが、プリコンパイル済みヘッダをやめる ことでうまくいきました。 (2) Form1.h内でのアンマネージドの呼び出しをすべて、アンマネージドでの グローバル関数経由としました。 どうも、一つのアンマネージドの関数をマネージドからとアンマネージドから 呼び出すと、アンマネージドからその関数の呼び出しが遅くなるようです。 (マネージドからの呼び出しはどこかにあるだけで、実際には呼び出さなくても 遅くなる) いったいどういう仕組みなのかご存知の方はご教授ください。
comboBox1を配置して、下記の様にすると、Form1.h[デザイン]が デザイナの読み込み時に、1つ以上のエラーが発生しました。 エラーは遺憾一覧表示されます。コードの変更の必要なエラーもありますが、 プロジェクトを再度ビルドすると解決できるエラーもあります。 C++ CodeDOM parser error: Line: 146, Column: 34 --- Unexpected token for a 'term' コンパイルも正常、プログラムも走るんだけど、どうしたら直りますかか? // comboBox1 // this->comboBox1->DropDownWidth = 150; array<Object^>^ objectArray = { "hoge_1", "hoge_2", "hoge_3", "hoge_4", "hoge_5", }; this->comboBox1->Items->AddRange( objectArray ); this->comboBox1->FormattingEnabled = true; this->comboBox1->Location = System::Drawing::Point(144, 75); this->comboBox1->Name = L"comboBox1"; this->comboBox1->Size = System::Drawing::Size(121, 20); this->comboBox1->TabIndex = 7;
スマソ ×エラーは遺憾一覧表示〜 ○エラーは以下に一覧表示〜
確かにエラーは遺憾だw
C++の命令一覧があるサイトはありませんか?
>>106 すみません、C++始めたばかりで良く分かりません。
命令(予約語ですか)一覧とそれを説明したサイトがあれば
学習しやすいかと思いまして。
C++ 始めたばかりで C++/CLI に手を出すもんじゃないし、 そもそも多分 C++/CLI じゃなくてただの C++ だろうから恐らくスレ違い。 そして命令一覧とかというと HSP 辺りから出てきた雰囲気。
>>108 スレ違いすみません。前はBASIC使ってました。
102ですが、スルーでしょうか?
>>110 永遠に遺憾に思いつづけておけ。そして二度と来るな
>>111 そういうお前も二度と来るな、いいな覚えておけ
馬鹿だろ、おまえら。いいかげんにしろ。
Cでソケット使うとき、WSAStartupの初期化を行いますが C++/CLIではSocket クラスを使うと思うのですが、どのメソッドを使ったら よいのでしょうか?
ヘルプにサンプル書いてある
116 :
デフォルトの名無しさん :2006/03/26(日) 18:04:07
C#で関数呼び出すのに public void hoge(string foo) こんなのがあったのですが、C++/CLI的に書くには どうしたらイイデツカ 当然これは駄目でした public void hoge(string^ foo)
C++の本を読め
C++スレできいてみる
>>116 public:
void hoge(System::String^ foo)
アクセス指定は個々の宣言につけるものではなく、続く宣言に対して一括で指定する。
C++/CLIにstring型は無いから、System::Stringにする必要がある。
Formのデザイナでエラーが出ないようにするには どうしたらいいのでしょうか?
作り直せ。
俺もそんな感じでフォーム作り直さなきゃならなくなったことがある。 どこまでぐちゃぐちゃにしたらパーサが困るのか試してみようと 思ったんだが、結構耐えれるみたいなんだよな・・・ フォームデザイナ用っぽい #pragma とか重要そうだよな。 それはそうと、複数のフォームをフォームデザイナで作って、 複数のスレッドから Application::Run(gcnew OreNoForm1); Application::Run(gcnew OreNoForm2); ってやってフォームを複数開くアプリケーションを作りたいんだけど、 こういうときって共通のデータはどうやって持つのがいいんだろう。 そして各フォームで発生したイベントのイベントハンドラから そのデータをどうやっていじるのが便利なんだろう。 できるだけフォームデザイナが生成したコードはいじらずに。 具体的にはシミュレーションの入力値をリアルタイムでいじる フォームと結果をリアルタイムで可視化するフォームを別に開く アプリケーションを作りたい。まぁ典型的なMVCモデルなんですが。
123 :
デフォルトの名無しさん :2006/03/31(金) 18:55:32
124 :
デフォルトの名無しさん :2006/03/31(金) 18:59:03
126 :
120 :2006/03/31(金) 22:48:39
>>121 ,122,125
ありがとうございます。
System::Windows::Forms::Controlから派生したクラス変数でエラーが出ているみたいでした。
このクラスはFormと同じ名前空間にありますが、namespaceを省略せずに
グローバルスコープ演算子のないフルネームで宣言して初期化したら、エラーが消えました。
127 :
デフォルトの名無しさん :2006/04/13(木) 17:39:42
メイン関数から複数のフォームを生成しているんですが、 フォーム間で共有するべきデータってどのように 保持するのが定番なんでしょうか?
ちなみにフォーム間で共有したいデータは、 ネイティブのものもありますし、 マネージドなオブジェクトもあります。
Singleton(厨御用達
その Singleton をフォームのクラスに渡すにあたって、 フォームデザイナが生成したフォームのクラスの コンストラクタをいじってしまっていいんでしょうか? フォームデザイナが生成したコードをいじると、 彼(彼女)が混乱をきたすのではないかと危惧しています。 以前いじりすぎて、「パースできん!」って怒られてしまい 泣く泣くフォームを作り直したことがあります。
シングルトンに渡すもくそもねーだろ。 コンストラクタがイヤならプロパティにすれば?
コンストラクタの注釈に「好きに弄ってくれ」って書いてなかったっけ?
>132 いや、ヤシはフォーム・デザイナが生成した、これは触るな、って書いてあるところを直接触って パースできなくなったのを棚に上げて、ここ以下に修正してくださいと記述してあるコンストラクタを いじって大丈夫か聞いてるんだ 不思議だろ?
#pragma region Windows Form Designer generated code の中を弄ったんか…。
おまいら、手厳しすぎ。もうちょい、くだすれらしくしてやれよ
C++/CLI用のツリーコンテナは用意されているのでしょうか?
ツリーコンテナ? TreeView や TreeNode 以外にあるの?
138 :
デフォルトの名無しさん :2006/04/15(土) 13:58:11
質問。 コンソールでコンパイルしようとしているんですが、 フォームを作ろうと System.Window.Forms をusing namepaseするとWindows以下の名前空間が見つからないという エラーが出ます。多分オプション辺りで決めるんでしょうが見当が付きません。 どなたかご存知ありませんか?
参照
140 :
138 :2006/04/15(土) 14:06:20
>>139 どういう意味でしょうか。
#using辺りの事でしょうか?
コンパイラの引数に /? をつけてヘルプ嫁
>>140 dllを参照の追加に設定してないんじゃない?
解決しました。 やはり#using指定がするだけでした。
144 :
デフォルトの名無しさん :2006/04/15(土) 19:09:33
すいません、質問です。 cppを間違えて消してしまい、 頑張って復元してみようと試みましたが、復元出来ませんでした。 ncb,vcproi,sln,objのどれかからcppを抽出できないでしょうか?
>>144 無理です。
復元するためのツール(Final Data とか)を使ってみても無理なら、
あきらめるしか有りません。世代バックアップの機能もVSに
入ってたらいいのに、なんて思うことは俺もあります。
あ、そういう人は Visual Source Safe を使うのか。
でも一人開発にはちょっとヘビーすぎる気もする。
かといって CVS は VS に統合されてないし。
ところで、Visual Source Safe って Microsoft Academic Alliance に含まれてましたっけ。含まれてたなら学校行ってインスコしようっと。 今は theSpoke Premium でもらった VS 2005 Professional 使ってます。
147 :
デフォルトの名無しさん :2006/04/15(土) 19:15:47
うひょ、今リスト見たら Visual Studio 2005 Tools for the Microsoft Office System (Dec 2005) Visual SourceSafe 2005 (Dec 2005) も含まれているそうな。ひゃっほ。 しかし VS 2005 Professional VS 2005 Tools for the Microsoft Office System って一緒にインスコできないのかな?CE 向けのアプリも作ってるけど、 同時に Outlook のプラグインも作りたくて。
148 :
デフォルトの名無しさん :2006/04/15(土) 19:26:04
>>145 レスありがとうございます。
ああ、やっぱり無理ですかorz
149 :
デフォルトの名無しさん :2006/04/15(土) 19:37:15
150 :
初心者 :2006/04/16(日) 05:53:02
CLI って何ですか? 詳しいサイトあったら教えてください。
>>150 だいたいCLI ≒ CLR ≒ .Net Frameworkと思えばよい。
正確には、CLIは.Netのクラスライブラリの仕様を定めたものであり、CLIの一実装がCLRであり、
.Net FrameworkはCLRと.Netプログラムを動かすための基盤などが含まれていると言ったところ。
152 :
デフォルトの名無しさん :2006/04/16(日) 14:34:33
CLI = クリ = クリトリス
152の頭が可哀想だ
Cのfreadに相当する関数はなんですか?
System::IO::FileStream::Read が一番近いんじゃね
以前から聞こうと思っていたのですが VC8で現在編集中のファイルを別名で保存するには どうしたらできますか
編集ったってアプリによってファイルをつかむタイミングが違うだろ? ファイルをオープンしてるのか、排他してるのか、それによるんでね?
なんだか、まどろっこしい回答だな VS2005で現在編集中のファイルを別名で保存したいんですが できるの?できないの?
>159 馬鹿だなぁ。貧乏人はやってみることもできないのか? ファイルのメニュー見れば出てくるだろ。これだからニート野郎は
もうめんどくさいからできない事にしておこう
163 :
デフォルトの名無しさん :2006/04/27(木) 22:53:27
>>161 は自らを
頭の(・∀・)イイ!!
金持ちと大言しています、もっと自慢してください
ちょっと待って! 今、VC「8」って言った , ,-;:;:;:;:;:;:;:;:;:;:;:;:;:;:;:ヽ /;:;:;:;:;:;:ミミ;:;:;:;:;:;:;:;:;:;`、 / ^ノ^ノ:^) /;:;:;:;:彡―ー-、_;:;:;:;:;:;:;:;| / _ノ_ノ_ノ /) |;:;:;:ノ、 `、;;:;:;:;:;:i / ノ ノノ// |;:/_ヽ ,,,,,,,,,, |;:;:;:;:;:;! ____/ ______ ノ | ' ゚ ''/ ┌。-、 |;:;:;:;:/ _.. r(" `ー" 、 ノ |` ノ( ヽ ソ |ノ|/ _. -‐ '"´ l l-、 ゙ ノ _,-ー| /_` ”' \ ノ __ . -‐ ' "´ l ヽ`ー''"ー'" | : | )ヾ三ニヽ /ヽ ' "´/`゙ ーァ' "´ ‐'"´ ヽ、`ー /ノ ヽ `、___,.-ー' | / / __.. -'-'" | | \ / | l / . -‐ '"´ \ |___>< / ヽ
初心者ですお願いします
http://dobon.net/vb/dotnet/form/openfiledialog.html にあるC#のコードをC++に移植したいのですが
教えてください。
[C#]
//OpenFileDialogクラスのインスタンスを作成
OpenFileDialog ofd = new OpenFileDialog();
//ダイアログを表示する
if (ofd.ShowDialog() == DialogResult.OK)
{
//OKボタンがクリックされたとき
//選択されたファイルを読み取り専用で開く
System.IO.Stream stream;
stream = ofd.OpenFile();
if (stream != null)
{
//内容を読み込み、表示する
System.IO.StreamReader sr =
new System.IO.StreamReader(stream);
Console.WriteLine(sr.ReadToEnd());
//閉じる
sr.Close();
stream.Close();
}
}
何を教えれば良いんだ?
というかそもそも本当に C++/CLI 使ってるんだろうな? MFC とか言ったりしないだろうな?
168 :
デフォルトの名無しさん :2006/04/29(土) 11:27:19
たんなる C++ かもしれんし・・・
165です、すみませんでした165のコードをVC8のコードに変換したいのですが よろしくお願いします
取りあえず自分でどう書いてみたのか書け。 丸投げされても困る。
165です、どうもです 下記のコードのような感じだと思うのですが System::IO.Stream stream; の部分が良く分かりません 他にもエラーは出るのですがとりあえず 'System::IO::StreamReader' の宣言を確認してください。 となってしまいます //OpenFileDialogクラスのインスタンスを作成 OpenFileDialog^ ofd = gcnew OpenFileDialog(); //ダイアログを表示する if (ofd->ShowDialog() == ::DialogResult::OK) { //OKボタンがクリックされたとき //選択されたファイルを読み取り専用で開く System::IO.Stream stream; stream = ofd->OpenFile(); if (stream != nullptr) { //内容を読み込み、表示する System::IO::StreamReader sr = gcnew System::IO::StreamReader(stream); Console::WriteLine(sr::ReadToEnd()); //閉じる sr->Close(); stream->Close(); } }
・ピリオド 換え忘れてる ・取りあえず参照型の宣言する型には ^ つけとけ
173 :
デフォルトの名無しさん :2006/04/30(日) 00:30:14
今NativeC++しかやってないんだけど、これからのことも考えてC++/CLIに移行したいと思ってるけど、直接C++/CLIを叩き始めるのはつらい? ManagedC++とかから扱い始めないと苦しいことになる?
MC++ は黒歴史になってる。全然気にしなくていい
今はまだ C++/CLI の情報が(特に日本語のは)ほとんど無いから手探り感が強いかもね CLI というか .NET に関しては C#/VB.NET のを参考にすることが多いだろうから読めたら便利
176 :
デフォルトの名無しさん :2006/04/30(日) 02:35:21
C++/CLIで LoadLibraryしたものを FreeLibraryするとアボンヌしちゃうんだけどなんでだろう? FreeLibraryしなくていいのかな...
え? 漏れLoadLibrary、FreeLibrary 使ってるけど、別にトラブったことないけど
>>174 , 175
ありがdm(__)m
CLIが.NETってこと?
それなら、わざわざC++/CLIをやりながら.NETをする必要がない気がする。
やっぱり英語の資料しか見つからない。
日本語でも莫大な資料を読むのは疲れるのに、英語となれば日本語に脳内変換しないといけないから余計に体力使う。
開発環境ってどうしたら作れますか?超初心者ですいません
180 :
176 :2006/04/30(日) 06:20:41
/clr でコンパイルするとやっぱりアボンヌしちゃうな。(Nativeだと大丈夫ぽい) 毎回アボンヌするわけじゃないんだけど、 記述の仕方によっては毎回なるのと、たまになるパターンがあった。 abone.dllでスレッド使ってるのが影響してるのかな? struct abone_dll { HMODULE m_dll; abone_dll(){m_dll = ::LoadLibraryA("abone.dll");} ~abone_dll(){::FreeLibrary(m_dll);} }; int main(){ abone_dll dll;}
>179 自力で調べて構成する能力がないなら、Express をDLするか、金出して買え 開発環境に手を出すのは、ちゃんとコード組めるようになってからでいい
StreamWriterクラスを使ってテキスト形式でファイルに書込む場合 System::Text::Encoding::GetEncoding("Shift_JIS")) でOKなんだけど ExcelのCSV形式の場合は何を使ったらいいのでしょうか? UTF-8でも文字化けするのですが・・・
System::Text::Encoding::Default でいいんじゃね?
Excel の csv 形式って、ただのテキスト・ファイルだろ ふつうにエディタでコンマ区切りの日本語文字列作って Excel で開いたが、特に 文字化けしないぞ。コードが悪いんじゃねぇか?
>185 Default で別に文字化けしないだろ? StreamWriter sw("Sample.csv", false, System::Text::Encoding::Default); sw.WriteLine("あああ, いいい, ううう, えええ, おおお"); sw.Close(); まさか、文字列を別に変換して StreamWriter に渡したりしてないよな
XMLドキュメントコメントを書くのめんどくさいんだけど C#みたいにタグを自動で入力してくれるようにならない?
アドオンを作れ サンプルなら CodeProject にある
192 :
デフォルトの名無しさん :2006/05/07(日) 11:44:02
配列プロパティってどうやって使うんですか? 教えてください。おねがい。
取りあえず考えてみたコードを書いて
194 :
デフォルトの名無しさん :2006/05/07(日) 11:52:43
ごめんなさい。 MSDNで探したら、即効見つかりました。 後で検索した人のために一応コピペでコードを。 property int default[int] { int get(int index) { return MyArr[index]; } void set(int index, int value) { MyArr[index] = value; } }
別に default でなく、明示的に名前付けしてもいいんだけどな
Stringクラスで最後の単語を取得するメッソッドってないですか? abc\def\ghi からghiを取り出したいのですが
そもそもお前が言う単語の定義が不明なのにどうしろと? 正規表現でとりだす 単語の区切りが \ のみ固定ならば LastIndexOf で Substring 後ろから自分で一文字ずつ見ていって Substring
>>197 サンキュー簡単にできたよ
Substringって2番目の引数省略したらLastIndexOfからファイルの最後までを返すんだね
ちょっと質問です。 今までC++Builderを使用していて、今度からVC++2005を使用します。 GUIアプリを作成を考えています。 フォーム上に配置したボタンのイベントが、全て.hファイルに作られてしまうのですが 処理内容も.hファイルに記述するのが普通なのでしょうか
いや、別に
漏れも何気にいつもhファイルに書いていたが、考えたらたしかに変だな?
WTL とかは普通にヘッダだろ?
質問です。 typedef の中身を知らずに、クラスの先行宣言て出来ないんでしょうか。 --- // コンパイルエラー class CHoge; class CTest; typedef CHoge CTest; --- // コンパイル出来る class CHoge; typedef CHoge CTest; typedef CHoge CTest; // 2度目 --- 単に別のヘッダファイルで typedef されているクラスの、ポインタを扱いたい だけなので、 include を避けたい、というのが目的です。 winxp vc++2005 宜しくお願いします。
そもそも名前衝突するような typedef するなってのが真っ当な対処だと思うが class CTest; で型名を宣言しているのに、同名の型名をさらに typedef すりゃ当然エラーでしょ typedef で別の名前にするか、namespace でくるんだら?
String型のデータをchar[]に変換するのってどうやんの Stringのメッソッドは沢山あるから、調べれば変換する必要ないかもしれないけど String^hoge = "abcdef"; //↓これはOKで array<Char>^foo = file->ToCharArray(); //↓これはなんでNGなんだろう? char[] foo = hoge->ToChaArray();
System::Char と char が全く別物だから .NET の配列と C の配列が全く別物だから System::Text::Encoding::GetBytes で array<System::Byte>^ 経由でコピーするか、 System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi でも使え。
ちなみに206の前者の方法では、 arrayからはコピーせずpin_ptrで固定してそのまま使うほうが効率的だと思う。
>>205 System::Charはwchar_t相当。
wchar_tの文字列でよければPtrToStringCharsをpin_ptrで固定すればよい。
>>205 ですが
>>208 の言ってるのはこういうこと?↓
String ^str = "Hello";
// Pin memory so GC can't move it while native function is called
pin_ptr<const wchar_t> wch = PtrToStringChars(str);
>>206 の書いてる2つの方法も見て見たいが、多い浮かばん・・・・・
>209 キーワードでググれよ
C++使えるのになんでCLIで製作するの? 誰もframeworkなんて持ってないのにさ
>>209 そういうこと。
wchはconst wchar_t*として使える。
ただstd::ostreamに出力するときにはstatic_castが必要だったけど。
213 :
デフォルトの名無しさん :2006/05/11(木) 19:58:51
Thread.SuspendとThread.Resumeは、互換性のために残されています。 SuspendとResumeの機能の代用はどうしますか? 定石があったら教えてください。お願いします。
スレッド自身に止まってもらうようお願いするんだ
1つ目 スレッドであるフラグを監視し、Thread.Sleep(Infinite) を実行し、 Thread.Interrupt で sleepを抜け出し、ThreadInterruptedException をキャッチし、スレッドをそのまま再開させる方法。 2つ目 セマフォか、クリィティカルセッションを使用して停止と再開を行う コードを書く。 の方法しかないの?
二つめ半だが、Mutex という手もあるな
VC++ 2005 Express Editionで、To.Stringが使えません。 自分がつくるどんなプログラムでも使えないので、 なにか名前空間に書くのかなと思ったのですが、いったいどうしたらよいのでしょう。 そのほかにも、string型の変数の宣言ができなかったりするので、string関係全てがダメなようなのですが・・。
-> だったりしないか? String^ だったりしないか?
>>218 textBox1->Text = test.ToString;
このような感じでやっているのですがだめなのでしょうか・・・
駄目だろ なんで、textBox1->Text なのに、代入する側は test.ToString() なんだよ
221 :
217 :2006/05/11(木) 22:55:41
自己解決しました!! ToStringの後に()を付け忘れていました!!いやはやこれだけだったとは・・・ みなさん本当にありがとうございました。
222 :
217 :2006/05/11(木) 22:56:35
>>220 レスをくださっていたのですか!更新をしていなくて・・・
申し訳ございませんでした。ありがとうございました。
リストビューを拡張スタイルで使う場合、コードの記述だけで使えますか? インクルードするヘッダとか、listview1で変更するプロパティ等があれば教えてください。
使えない理由があるなら、教えてください。できれば、コンパイル・エラーも一緒に
一行反転させようと思い ↓こう書きましたがエラーが出ます ListView_SetExtendedListViewStyle( m_listctrl.m_hWnd, LVS_EX_FULLROWSELECT ); : error C2065: 'm_listctrl' : 定義されていない識別子です。 : error C2228: '.m_hWnd' の左側はクラス、構造体、共用体でなければなりません型は'unknown-type' です。 : error C2065: 'LVS_EX_FULLROWSELECT' : 定義されていない識別子です。 : error C3861: 'ListView_SetExtendedListViewStyle': 識別子が見つかりませんでした
>225 C++/CLIとは全然関係ないですね。それはともかく、そもそも、m_listctrl メンバが存在していないのに Win32 の拡張スタイル指定をしても無駄です
そっか、変な感じがしてました 「リストビュー 拡張スタイル VC++」で ググッテもでてこないんだよな的確なやつが リストビューの拡張クラス教えて下さい
・・・あはぁ? えっと、あなたのやりたいだろうことについて言えば、適切な ListView の ウィンドウハンドルに対して、ListView_SetExtendedListViewStyle でいいのですけど あなたはまず、適切な ListView のウィンドウ・ハンドルを取得するところが間違って いるんです
Syntax void ListView_SetExtendedListViewStyle( HWND hwndLV, DWORD dwExStyle ); Parameters hwndLV Handle to the list-view control that will receive the style change. dwExStyle DWORD value that specifies the extended list-view control style. This parameter can be a combination of extended styles. (´ε`;)ウーン…わからん
黒歴史らしいmanaged C++からC++/CLIに乗り換えようと思ってテンプレの変換ガイドを読んだんだが、 これはやはり自分で書き換えていくしかないのか? 自動でやってくれる変換ツールなんてものはないのか?
ない。それに、それほど難しくはないし
234 :
デフォルトの名無しさん :2006/05/18(木) 22:44:13
WIN XP SP2です TcpClient.Client でメール送信を行う場合 文字セットの形はUTF-8なのでしょうか? message->Body = Message; で送信したテキストをOutlookExpressで受信した場合は良いのですが 携帯(Docomo)でだと文字化けしています
TcpClient とは何の関係もないな MailMessage に BodyEncoding があるだろ
237 :
デフォルトの名無しさん :2006/05/19(金) 21:21:00
MailMessage myMail = gcnew MailMessage();{ 適当に宣言 } System::Net::Mail::MailMessage' : クラスはコピー コンストラクタを含んでいません 構造体の引数が足らないって事?
MailMessage は構造体じゃなくてクラスだし。 gcnew で取得できるのはハンドルなので ^ が必要。
239 :
デフォルトの名無しさん :2006/05/20(土) 01:20:03
C++/CLIの入門学習におすすめなものってありますか?
つ プログラミング言語C++第三版 つ Essential .NET つ プログラミング C# 言語解説 つ C++/CLI 言語仕様書
>>238 スマソ
お主の言う通りじゃ
拙者以前MailMessageクラスでメーラ作っていたの忘れておった
242 :
デフォルトの名無しさん :2006/05/20(土) 14:53:11
>>240 C++/CLIって敷居が高いんですね。
入門学習に仕様書や他の言語の上級者向けの本を読まなくちゃいけないなんて。
>>242 単に参考にする本や情報がないだけ
おまいさんが入門書やサイトを作ってくれれば、このスレの神になれるよ
C:\WINNT\system32\ 内のdllをインポートしようとしたら #import "C:\WINNT\system32\foo.dll" error C2812: #import は /clr:pure および /clr:safe でサポートされていません リンカの設定を混在にしても駄目だった どうしたらいい?
>>244 プロジェクトのプロパティの構成プロパティの全般の共通言語ランタイムサポートを/clrにするのではないかと思う。
>244 対応する lib を使うか、参照で取り込んだら?
変な日本語かも知れませんがお許しください レジストリの値を取得してファイルに書き込みたいのですが GUIDというものを知りました、調べたら 「UUIDを16進数32桁の文字列形式で表現する標準的な方法を定め、これをGUIDと呼んでいる。」とあり、下記の様に書いて見ました StreamWriter^ sw = gcnew ("C:\\foo.txt", false,System::Text::Encoding::GetEncoding("Shift_JIS")); 省略 sw->Write(Conver::ToString(typeGUID,16)); ここで error C2653: 'Convert' : 識別子がクラス名でも名前空間名でもありません。 error C3861: 'ToString': 識別子が見つかりませんでした となってしまいます、お助けください。
using namespace System; を宣言してないのなら、完全限定名 System::Convert を使わないと駄目
>247 何をしようとしているのか謎だけどレジストリを触るなら つ Microsoft.Win32.Registry
>>247 , 248
246です
sw->Write(System::Convert::ToString(typeGUID,16));
としたら
error C2665: 'System::Convert::ToString' : 37 オーバーロードのどれも、すべての引数の型を変換できませんでした
c:\winnt\microsoft.net\framework\v2.0.50727\mscorlib.dll: 'System::String ^System::Convert::ToString(System::Object ^,System::IFormatProvider ^)' の可能性があります。
c:\winnt\microsoft.net\framework\v2.0.50727\mscorlib.dll: または 'System::String ^System::Convert::ToString(bool,System::IFormatProvider ^)'
省略(約20のエラーMess)
c:\winnt\microsoft.net\framework\v2.0.50727\mscorlib.dll: または 'System::String ^System::Convert::ToString(int,int)'
c:\winnt\microsoft.net\framework\v2.0.50727\mscorlib.dll: または 'System::String ^System::Convert::ToString(__int64,int)'
引数リスト '(GUID, int)' を一致させようとしているとき
どうしたものでしょう?
要するに Guid を文字列にしたいってこと? その Guid は System::Guid オブジェクトなのか、ネイティブの GUID 構造体なのかどっちだ? 前者ならインスタンスの ToString メソッド使えばいい話だが。
c++を学ぶのに最適な参考書って何ですか?
まずは K&R 嫁
Nativeです Cなら printf("typeGUID = %.8x\n",typeGUID); これで終わることなのですが、はまっています
Guid 構造体にも ToString メソッドついてるだろ printf("#s\n", typeGUID.ToString()); でいけるはずだが
あ、# -> % な sw->Write(typeGUID.ToString()); で、済むと思うが、MSDN ちゃんと見てるか?
247です
>>256 いまだに解決できていません
printf("#s\n", typeGUID.ToString());
error C2819: クラス '_GUID' にはオーバーロードされたメンバ 'operator ->' がありません。
C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\include\guiddef.h(22) : '_GUID' の宣言を確認してください。
代わりに '.' を使用しますか?
error C2039: 'ToString' : '_GUID' のメンバではありません。
C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\include\guiddef.h(22) : '_GUID' の宣言を確認してください。
error C2039: 'ToString' : '_GUID' のメンバではありません。
C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\include\guiddef.h(22) : '_GUID' の宣言を確認してください。
_GUIDを見ると、このように定義付けられています。
#ifndef GUID_DEFINED
#define GUID_DEFINED
#if defined(__midl)
typedef struct {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
byte Data4[ 8 ];
} GUID;
#else
typedef struct _GUID {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[ 8 ];
} GUID;
#endif
#endif
スマソ肝心なこと忘れてた 上記のエラーコードはこう書いた時の場合です sw->Write(typeGUID.ToString());
そりゃー、ネイティブの GUID に ToString が定義されてるはずもないわな。 昔のやり方が好きなら、sprintf でも使えばいいんじゃない? そうすれば、String^ のコンストラクタには SByte* 引数に取るのもあるし。
>257 これは読んだか? ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.ja/dv_vccore/html/022c934c-3395-4f04-b498-85ad9bf8c646.htm
>>257 なんで System::Guid を使わないんだか不思議なんだが。
>>260 今はじめて読んだなんか難しそうだな
引数に
GUID ng = {0x11111111,0x2222,0x3333,0x44,0x55,0x55,0x55,0x55,0x55,0x55,0x55};
Guid mg;
を渡しているようだが、おいらの場合は何を渡していいかわからんし・・・
>>261 System::Guidを使ったら幸せになれるかな?
>>262 幸せになれるかどうかは知ったことではないが、適当なGUIDを生成して書き出したいだけならこれだけだぞ。
System::Guid guid = System::Guid::NewGuid();
System::Console::WriteLine(guid);
ちなみにネイティブな関数でGUIDを文字列にするにはStringFromGUID2。
>>262 そのngの中身は適当。深い意味は無い。
単にSystem::Guidと::_GUIDとを変換する関数を使用する例。
>>263 少し幸せになれそうでしたが、やっぱり問題があります
GUID typeGUID;
while(spEnumTypes->raw_Next(1,&typeGUID,0) == S_OK){
printf("typeGUID = %.8x\n",typeGUID);
System::Guid guid = System::Guid::NewGuid();
System::Console::WriteLine(guid);
}
と出力すると下記の様にtypeGUIDとGUID(System::Console::WriteLine(guid);)の値が異なります
ためしに
System::Console::WriteLine("{0,x8}",guid);
としたら例外エラーが出ます。
typeGUID = 14d96c20
9e65796a-875c-48a7-ac87-bad43680de8e
typeGUID = 220d5cc1
29109995-ac32-4108-9f87-dac14251c3a8
typeGUID = 5e7e8100
f3750553-a6a2-4307-a940-3d1684f14236
typeGUID = 89c39569
e3f1b21b-7a29-4c9c-872c-07629453f52f
typeGUID = e161255a
8f6f3791-1e05-42b4-9d1f-5d821c472a82
当たり前だろ。新しいGUIDを生成してるんだから 例外エラーだって、出力フォーマットの問題だろ? >260 のMSDNに載っているようにやればいいじゃないか せっかく、ToGuid や FromGuid っていう相互変換サンプルが記述されているのに typeGUID を取得したら、 Guid mg = FromGUID( ng ); として、それを Console::WriteLine("{0}", mg); としてやればいいだろ
>>265 それじゃマネージドのことはすべて忘れてネイティブの世界でかってにやってくれ。
ん、偉そうに言って間違えた Guid mg = FromGUID( typeGUID ); だな
て言うか何故GUIDに %.8x なんだろ
Guid の実体って 128 ビットの整数だよな。そもそも質問者はレジストリ操作したいんじゃ なかったのか? だから、>249 を示したんだが、華麗にスルーされてるし
元の質問者は未だGUID(_GUID)とSystem::GUIDの区別が付いていないだけだろ。
System:: と書くからには Guid と書こうぜー
そうだな。まず俺も区別が付いていなかったようだ。
247です、みなさん色々教えてもらってありがd
>>268 よろしく
Guid mg = FromGUID( typeGUID );
としたら
error C3861: 'FromGUID': 識別子が見つかりませんでした
となるのですが
>274 いや、だから、それは >260 の MSDN のサンプルに相互の変換関数として定義されていると 書いてあるだろ
276 :
デフォルトの名無しさん :2006/05/24(水) 08:28:22
C++CLIのコンパイラを無料で使うにはVC++2005EXpressをインストールするしかない?
.NET Framework 2.0 の SDK 入れるだけでも良かったはずだが
ManagedC++でコンパイルされたライブラリを C++/CLIのアプリにリンクすることは可能?
>279 アセンブリ化されていれば可能
.NETアプリでJavaアプレットみたいなことは できるんでしょうか?(サーバなしで)
できないことはないが自由度は低め。
質問。C#,VB.netがある程度できるから、 C++/CLIもやってみたら、 ILDASMで覗いたら、クラス/構造体のメンバでない関数が、いきなり 関数が定義されているんだけど・・・。 いいのか、これ!?
284 :
283 :2006/05/25(木) 22:24:25
うわ、日本語がおかしい・・・('A')
別に CLI 的に駄目とか言う訳じゃないし。 C#/VB 的に駄目なだけで。
System.Reflection.Emit.ModuleBuilder には昔から DefineGlobalMethod なんてメソッドがある。
C++CLIに出来なくてIL的に書けるコードってあるの?
メンバ名に記号使うとか
>>286 へぇ〜。
C#,VBでグローバル関数が宣言できないのは、「オブジェクト指向で書きやがれ、ゴルァ」ってことなのかな
一応、仕様的にはグローバル関数は駄目なんだけどね
>>275 274です、おそくなりました、やっとお礼が書けます
>260のMSDNのサンプルって
GUIDと_GUIDを変換して戻り値としてその構造体のポインタを返すという
内容なんですよね?
C言語の基本でしたスマン
>>291 構造体ではなく、構造体の値そのものを返している。
日経ソフトウェアで、C++/CLIで始める.NETなんて記事があったから 読んでみたら、いい感じなのな。VB並みに冗長なのはちょっとあれだけど、 C#よりこっちのほうがいいような。
漏れも今買ってきたYO 雑誌なので内容は浅薄なのは否めないけれど、こと活字によるVS8の 情報に飢えているだけに貴重な一冊えある MSDNでいつ読んでも意味が分からなかった propertyが理解できたが、実際どのような場面で アクセサ・メソッドを使うのかまた、疑問が一つふえた ・゚・(ノ∀`)・゚・。藁
>>294 メソッドの呼び出しを強要できる点。
変数っぽくアクセスできるけど、実態はメソッドの呼び出しだから。
Console::WriteLineで数値を頭から4文字出力したい場合 Console::WriteLine("{0,4}",foo); これで合ってますか?
なぜ試さない
298 :
デフォルトの名無しさん :2006/06/03(土) 07:57:00
超初心者の質問さしてください プリコンパイル済みヘッダ無しだと普通にmainがエントリポイント プリコンパイル済みヘッダを入れるとエントリポイントが_tmain 32apiだとWINAPI WinMain で、C++/CLIだとまた変わるんですか? C++/CLIは専用の書籍とか出てるんですか? 32apiやCやC++ならわかるんですがC++/CLIってさわったことが無い というか、知識が無いのでコードの書き方すら知りません。 どなたかこの超初心者の質問に、しぶしぶお答え願えないでしょうか
>>298 プリコンパイルドヘッダをインクルードすると_tmainになるでは無く、
<tchar.h>をインクルードすると、_tmainを使うことになる。
VC++のウィザードでプリコンパイルドヘッダを使うようにするともれなく、
stdafx.hの中に<tchar.h>のインクルードが記述されるというだけ。
mainから始めたければstdafx.hの中に<tchar.h>のインクルードを削除すればよい。
300 :
298 :2006/06/03(土) 08:48:26
ほーなるほど。 いっつもwin32アプリケーションウィーザードで windowsアプリならかってにプリコンパイル済みにチェックついて 特にファイルがすでに何か存在するわけでも無いので 新規追加のソース用ファイルでWINAPI WinMainからはじめるし コンソールなら必ずプリコンパイル済みヘッダーのチェックはずして mainから初めてたので初めて知った。 <tchar.h>って憶するにUNICODE用なのかな つかったことねーからわっかんねーや
301 :
デフォルトの名無しさん :2006/06/03(土) 09:31:26
302 :
298 :2006/06/03(土) 16:12:23
>>301 なるほど、リンク先のmsdn見ると
文字コードを自分で#defineで定義して
使い分けするためのものなんだ。
既定でマルチバイトか。
<tchar.h>は上手く使わないと、文字コード
が煩雑になっちまいそうだな。
あと、流し読みですがmsdn見てるとGCを使ってるようで
その他にも制約等があるんですね。
こりゃ普通のC++とはいかなそうで。
C/C++でwin32APIつかって、ウィンドウズのプログラム打てたとしても
(ウィンドウズ用でなくてもコンソール用でも)
C++/CLIでソースを書いていく上では、まったく別物ととらえるべきなんでしょうか。
ところで、C++/CLIの専門書籍って出てるんですか?
それともMSDNでなんとかするしかないんすかね。
なんか俺の質問内容見てるとくずたれその物の質問だな。
めんどくさいとお思いでしょうが、どなたか教えて頂きたいです。
>>302 C++/CLIは.NETが関係しない部分は従来のC++として扱える。(そうなるように作られている)
304 :
デフォルトの名無しさん :2006/06/08(木) 20:45:07
アンマネージドのオブジェクトのポインタと、マネージドオブジェクトをマネージドのCollectionなどで一緒に扱いたいのですが、 マネージドのコレクションでアンマネージドのポインタを保持する方法がわかりません。 やりたいのはこんな感じです。 System::Collections::Generic::KeyValuePair< UnManagedObject*, System::Windows::Forms::TreeNode^ > TreeNodePair; どなたかご教授いただけませんか? よろしくお願いします!!
307 :
デフォルトの名無しさん :2006/06/09(金) 11:44:39
304です。 305のwrapperクラス便利ですね。勉強になりました! 306さんもありがとうございます!!
text to speechを使って発声するプログラムを書いています。 発声のピッチとボリュームを変化させたく思っているのですが…。 using namespace SpeechLib; --------------------------- private: SpVoiceClass^ obj_SVC; --------------------------- //再生ボタンを押したとき String^ text = text_speak->Text;//テキストボックスの内容をtextストリームへ保存 obj_SVC->Speak(text,SpeechVoiceSpeakFlags::SVSFlagsAsync);//発声 //トラックバー(ピッチ) obj_SVC->SetRate((unsigned short)this->tone_level->Value); ------------------------- みたいな感じで書いています。 ツールで配置した再生ボタンとトラックバーについて、同じobj_SVCが使えるのでしょうか・・・・ コンパイルは通りますが、実際中身が入っていないようで・・・ どうしたらクラスを超えてobj_SVCを共有できるのでしょうか
309 :
298 :2006/06/14(水) 04:12:54
遅レスすいません
>>303 さん
レスありがとうございます
310 :
308 :2006/06/14(水) 06:25:14
VS2003でマネージ拡張をONにして作業しています, 要素数不明のクラス配列をforでまわさないといけないんですが, その場合の要素数取得の方法が分かりません. sizeof()はマネージ型には適応できないといわれます... どなたか教えていただけませんか?
Length CLI では配列もオブジェクトだぜ
>>312 EqualsやGetTypeが追加されているのは知っているのですが,
Length へのアクセスってどうやるのでしょうか?
public __gc class B {
public:
A __gc* a[]; //AはBと同じような形のクラス.
};
b->a->Length();
ではできませんでした.
こういう形のときにa[]の要素を知りたいのです
申し訳ありませんが,もうすこしお願いします.
…ん?2003?
315 :
311 :2006/06/14(水) 20:27:53
>>314 VisualStudio.net 2003で作業しています.
もしかし2005のみの機能ですか・・・?
できませんでしたじゃなくてエラーの内容を書け。 そりゃ Length はメソッドじゃないもんな。 ->Length か ->get_Length() を使わないと。
なんどもすみません
>>316 エラーというか...
その要素を持っていないようです.
public:
Equals(), GetHashCode(), GetType(), ReferenceEquals(), ToString()
protected: // と思われる.
MemberwiseClone(), Finalize(),
先ほどの式で
b->a->としたときに出る候補は以上です.
ちなみに b->a. は要素が出ませんでした.
症状がさっぱり分からんな。 #using <mscorlib.dll> public __gc class A { }; public __gc class B { public : A __gc* a[]; // A* a __gc[]; // Managed C++ 的にはこっちの方が相応しい希ガス }; int main() { B* b = __gc new B(); b->a = __gc new A* __gc[23]; System::Console::WriteLine(b->a->Length); }
319 :
311 :2006/06/14(水) 21:26:53
すみません,とんでもない初歩的なミスでした, 参照するクラスを書いたヘッダファイルを間違えていました. 別フォルダの以前のヘッダを参照していたみたいで(当時は配列にしていない) それでうまく言っていなかったみたいです.. 本当にご迷惑おかけしました.
なあんだ でも2003はインテリセンスがうまく働かないよね
visual studio .net 2005でC++の #include <iostream> using namespace std; を書いて、コンパイルすると \microsoft visual studio 8\vc\include\cstdlib(21) : error C2143: 構文エラー : '{' が ':' の前にありません。 と、言うようなエラーが100個以上出てきてコンパイルが通りません。 どうすればいいのでしょうか?
322 :
321 :2006/06/22(木) 19:46:11
すいません。 cppになってませんでした。ご迷惑おかけしました。
323 :
デフォルトの名無しさん :2006/06/30(金) 23:41:02
今windowsプログラミングの勉強中なのですが、 TextOut関数とCreateFontで文字出力にチャレンジしたところ、文字の背景に対する引数がないことに気がつきました。 背景を設定できる文字出力関数はどういうものがありますか?
>>323 TextOutの前にSetBkColorを呼ぶと、TextOutするときの背景色を指定できる。
325 :
323 :2006/07/01(土) 23:34:04
326 :
デフォルトの名無しさん :2006/07/02(日) 03:16:32
.netでC++を使う意味ってあるのか?
>>326 1. 既存の資産を.NETへ持っていける。
2. .NETは便利そうだ。でもC++はそれ以上にやめられない。(俺)
328 :
デフォルトの名無しさん :2006/07/04(火) 11:09:21
pin_ptr<> でマネージドオブジェクトを固定化したあと、 その固定が解けるのは pin_ptr<> がスコープからはずれて 消滅したタイミング? あと、わざと固定化せずにランタイムエラーが出るような コードを作って実験してみたいんだけど、どうすればいいですか?
329 :
デフォルトの名無しさん :2006/07/04(火) 12:07:58
_tempnam() で作成した一時ファイルに、プログラム起動中の一時データを保存しているのだが、 ノートンシステムワークスを併用している人から、プログラムが死ぬと連絡がきた。 調べてみると、プログラム起動中に、ノートンシステムワークスのクリーンアップを実行(by スケジューラ)すると、 一時フォルダ下の全ファイルが消されてしまい、プログラムはデータを失ってクラッシュした。 Windowsのディスククリーンアップなら、数日以内に作成されたファイルは消さないので問題は起きない。 一時ファイルをopenしっぱなしにしておけば、ノートンも消さない(消せない)ようだが、大量に一時ファイルを作るので、 ファイルハンドル数を食いつぶすのは避けたい。 何か良い回避方法があれば教えてください。
C:\temp に置かない
331 :
デフォルトの名無しさん :2006/07/04(火) 13:04:17
転んでも泣かない
C# の where に相当するキーワードって C++/CLI にはないの?
334 :
332 :2006/07/07(金) 23:24:20
>>333 ありがとう。C++ はそれなりに経験あるんだが、C++/CLI はまだ勝手がわからなくて。
昨日は、template のほかに generic ってキーワードがあることに気がつかず、
半日無駄にしてしまったよ・・・orz
C++/CLI で推奨されてる命名規則ってありますか? ハンガリアン記法が非推奨なのは知ってますが、 スコープ位は区別したいんですが。
他のアセンブリ(dll/exe)から見えないところなら自由だ。
338 :
335 :2006/07/08(土) 16:21:22
ボタンの大きさ位置等を変えられる簡単なスキン機能を 実装したいと思ってます。 Windows::Forms::Form を Xml にシリアライズするサンプルって どこかにないでしょうか?
delegate void ThreaderDele();//作成して public: event ThreaderDele^ OnThreader;//をつくって void TThreadTimer::Threader() { while (f_bTerminator) { Thread::Sleep(10000); if (!(OnThreader == nullptr)) { OnThreader(); } } f_Thread->Abort(); } 上記のようなEventを作成したいのですが「error C3918: 使用するには、'OnThreader' がデータ メンバでなければなりません」っと
Errorになります この場合どう記述すればErrorがなくなるのでしょうか?
OnThreader->raise(); じゃなかったっけ?
C++/CLI では event は実装(デリゲートインスタンス)が隠蔽される。 NULL チェックしちゃ駄目。OnThreader はデリゲートインスタンスではないから。 // C# の呼び出し側に null チェックさせる仕様もいい加減やめて欲しいな……。
344 :
デフォルトの名無しさん :2006/07/19(水) 17:22:57
多分ここでよいとは思うのですが、スレ違いなら誘導していただけると助かります
public value class A{...};
Void Sub(){
try{
A^ vcA = gcnew A(); // 値クラスをマネージヒープ上に確保?
...
//delete vcA; // 必要でしょうか?
} // try
catch(...){
} // catch
}
int main(array<String^>^ astrArgs){
Sub();
...
return 0;
}
VisualStudio2005(C++/CLR)での参照クラスと値クラスで混乱しています。上記のように
値クラスをマネージヒープ上に確保しているように見えるコードを書いても、↓によると
ttp://forums.microsoft.com/msdn-ja/ShowPost.aspx?PostID=395212&SiteId=7 実際には、値クラスはスタックに確保されているという情報を得ました。ここで疑問なの
ですが、gcnewを使って確保した値クラスのインスタンスはガーベージコレクトされないの
でしょうか?、またされない場合はコメントアウトのコードの様にdeleteで解放すれば良い
のでしょうか?。ご教示の程よろしくお願いします
>>344 それのどこを読んでいるんだ?こう書いてあるだろ。
----
ちがいます。
Int32^ a = gcnew Int32(10);
gcnewをつかえばスタック上に作成し、その値をボクシングした値を取得することができます。
----
ボクシングってのはマネ−ジヒープに新たなオブジェクトを作って、
そこへボクシング元のオブジェクトをコピーすること。
ようするにマネージヒープ上に値型のオブジェクトは存在しうる。
そしてそれはマネージヒープだからGCの対象。
特に必要でない限り、deleteしなくてよい。
どこかにクラスを網羅した表ってないですか? タイマーどこだーーーーー。むきぃーーーーーーー。
MSDN クラス数だけで何千何万の世界だぜ
どなたか、Image同士の矩形転送、カラーキー抜き転送、アルファ抜き転送のしかたをご存知ありませんか?
349 :
デフォルトの名無しさん :2006/07/20(木) 03:18:24
お初です 今日からCをはじめよめた者です 猫でもわかる〜と言う本を買ってそれで学ぼうと思ったのですが・・・。 いきなり大きな障害が C++Builder 5を使おうと思っているのですか うまく動いてくれないんです メモ帳で #include <stdio.h> int main() { printf("Hello World\n"); return 0; } これを.cで保存してコマンドプロントで実行したら HelloWorld と出るはずなのですが Borlanb C++ 5.5.1 for win32 Copyright (c) 1933,2000 Borland HelloWorld.c; Turbo Incremental Link 5.00 Copyright (c) 1997,2000 Borland C:\work> と出るのです これは何が悪いのでしょうか? 助言よろしくお願いします
>>349 つ 【初心者歓迎】C/C++室 Ver.29【環境依存OK】
>>345 理解できました。ありがとう
「ボクシング」ってそういう意味だったんだね
352 :
348 :2006/07/20(木) 10:52:49
せっかく色々手を抜けると思ったのに、これじゃゲームが作れない・・・。XP
354 :
デフォルトの名無しさん :2006/07/20(木) 11:13:31
>>353 レスさんきゅー。
プロトタイプ製作なので、速度はあんまり考慮してないんです。
Graphics::DrawImageは軽く使ってみたけど、
任意の画像幅に拡大縮小されちゃうみたいで、
期待していた効果とはちょっと違うなー。と。
BitBltとかAlphaBltみたいなのさがしてるんです。
まー、向こうで聞いてみます。さんきゅー。
355 :
354 :2006/07/20(木) 11:19:23
DrawImageUnscaledAndClippedっていうのがあったね。 盲目だった。
356 :
デフォルトの名無しさん :2006/07/20(木) 13:17:43
コンパイラオプションで呼び出し規約変わるんだね。 GetProcAddressから関数ポインタにキャストするときに 規約なしの関数ポインタ宣言しててはまった。 /clr -> void(__cdecl*)(void) /clr:pure -> void(__clrcall*)(void) #include<typeinfo> #include<string> #include<iostream> typedef void(*fn_type)(void); int main() { std::cout << typeid(fn_type).name() << std::endl; }
357 :
デフォルトの名無しさん :2006/07/20(木) 15:32:03
>350 板違いでしたか・・・。 誘導サンクスです 早速そちらに行きたいと思います またこっちに書き込むことがありましたらよろしくお願いします
358 :
デフォルトの名無しさん :2006/07/21(金) 12:19:44
VS2005Stdを使ってます 呼び出したメソッドで発生した例外を、上位のメソッドにそのまま投げたいのですが、 ↓のように発生するすべての例外についてcatchを記述する方法しかないんでしょうか? catch(...)みたいに、すべて一括で処理できる方法があれば教えてください Void Sub(Void){ try{...} catch(exp1){throw exp1} catch(exp2){throw exp1} : : catch(expN){throw expN} } int main(array<String^>^ Args){ try{ Sub(); } catch(...){ } }
359 :
358 :2006/07/21(金) 14:28:24
解決しました。あらためて調べてみたら↓でできる事がわかりました。 しかも、C++/CLIじゃなくて、標準C++の質問をしてしまったようで…… スレ違いの質問をしてしまって申し訳ありませんでした Void Sub(Void){ try{ ... } catch(...){ throw ; } }
待て待て。そんなことしなても、 catchしなければ勝手に例外は呼出元まで伝播するぞ。
361 :
デフォルトの名無しさん :2006/07/24(月) 10:43:54
誰かいますか?
いないよ
363 :
デフォルトの名無しさん :2006/07/24(月) 12:22:29
そうですか、失礼しました。
364 :
デフォルトの名無しさん :2006/07/24(月) 17:55:14
CLIとはなんですか?
トリス
int main(){ 0 != 0 ? return 0 : return 0 ; } このコードで\main.cpp(1) : error C2059: 構文エラー : 'return'というエラーが出るのですが、なぜでしょうか? ループ中にbreakを同じように使ったときも同じようなエラーが出ました 開発環境はVC++ 2005 Express Editionです
黙って return 0 != 0 ? 0 : 0; にしとけ
>>366 returnもbreakも式ではないので、式の中には書けない。(ちなみにthrowは式)
return 0 != 0 ? 0 : 0;と書きなさい。
>>367-368 そういうことだったんですね。
教えてもらったようにreturn 0 != 0 ? 0 : 0;と書くようにします。
回答ありがとうございました。
370 :
デフォルトの名無しさん :2006/07/25(火) 12:47:06
アドバイスをお願いしたいです。 「プログラムを作ろう!パソコン教科書 Microsoft Visual C++ 2005 Express Edition入門」 1995円 WINGSプロジェクト 青木 淳夫 山田 祥寛 (単行本 - 2006/3) ↑を買おうかと思ってるのですが、似たような内容のものが、手に入らないかなと思っています。 本屋で読んだ所、操作方法を例題をやりながら、覚えていく感じでしたので 初歩的な操作法を解説しいて印刷可能なサイトなどがあったら 教えてもらえないでしょうか。 よろしくお願いします。
小さな画像をドラッグで移動できるようにしたいのですが何を使ったらいいでしょう?
372 :
デフォルトの名無しさん :2006/07/25(火) 15:46:35
あげわすれました
たった一文の事なのに、それでも考えられる状況は結構幅広いんだ
374 :
371 :2006/07/26(水) 14:12:22
すいません。 windowsのファイルをドラッグして移動するように ドラッグ中にマウスポインタと画像が一緒に動くようにするには どうすれば良いかが分かりません。 マウスイベントから内部の情報を変更するところは見通しがついているのですが。
375 :
デフォルトの名無しさん :2006/07/26(水) 20:59:19
初心者ですが質問です。 c#と相互運用するためにはdllが必要であることを知りました。 どうすれば.net2005でdllを作成することができるのでしょうか?
テンプレートでクラスライブラリとかなんかそんなの選べ 後でプロジェクトのプロパティを変更でも良いが
377 :
375 :2006/07/26(水) 21:07:10
ありがとうございます。 早速試してみます。
378 :
375 :2006/07/26(水) 23:10:59
クラスライブラリで作成したプロジェクトを実行するときに、 "デバッグで使用する実行可能ファイル名"を要求されます。 dllしか作成されていないためexeファイルは存在しておらず、 該当ファイルが無いように思えるのですがどうすればよいのでしょうか?
>>378 クラスライブラリをデバッグするためだけのプロジェクトを追加すればいい。
380 :
デフォルトの名無しさん :2006/07/27(木) 02:14:50
VC++(Ver6.0)で、「スライダー」コントロールを使いたいのですが、 スライダーを使ったプログラム例が紹介されてる 書籍かサイトなどがあったらおしえてください。 「リストボックス」や「ラジオボタン」は入門書を参考にして なんとか使えるようになったのですが、 「スライダー」のプログラムに関する本がみつからなくて・・。
>>380 つ くだすれVisual C++(超初心者用)その3
ふたつの array を一つにしたいときって、 array<T^>^ foo=gcnew array<T^>(bar->Length+baz->Lenght); とやってコピーする以外に、もっと簡単な方法ないですか?
あー、 List<T^> foo(bar); foo.AddRange(bar); array<T^>^ result = foo.ToArray(); ではあかんの?
くだらない質問なのですが、C++/CLIでEUC漢字コードのテキストファイルを 処理するツールを書こうかと思うんだが EUC→SJIS→UNICODE→処理する→SJIS→EUC みたいな流れになって スマートじゃない stringをつかってEUCコードの文字列を直接使う方法ないですか?
100歩譲ってEUC→SJIS、SJIS→EUCの部分はそのままでいいとしても Unicodeに変換させずに処理させる方法とかないでしょうか? 情報の欠落が心配なので・・
つ std::string
>384 普通こうじゃないのか? EUC→UNICODE→処理する→EUC
EUC-JPはEUC-JPでも、CP51932の方ならCP932 (いわゆるシフトJIS)と一対一に変換できるはず。 非効率ということに変わりは無いけれど。
どこから SJIS が混入したんだろう
普通にCP932のまま扱えばいいんじゃ? 既存の関数は使えるわけだし
391 :
384 :2006/07/28(金) 01:00:30
EUCとSJISの間の変換は可逆的で安心なのですが Unicodeが絡んでくると、単純にEUC→Unicode→EUCをしただけでも 元通りに戻る保証ないですよね・・・? C++/CliのstringはUnicode専用だと聞いたのですが認識が間違っていますか? あと、SJISを経由する必要はありませんでしたね。申し訳ないです。
>391 390 は既存のマルチバイト操作を使えばいいんじゃないって意味 CLI の String 型はユニコードだから変換すればその通りだけど、バイト列を直接mbstrlen とかで操作する分には大丈夫なんじゃないの?
ま、.NET の文字列系はその辺が問題になるのなら使えん罠
>>391 だからCLIのStringじゃなく、std::stringとかC文字列を使ったらって言われてるじゃん。
そのためのC++/CLIだ。
395 :
382 :2006/07/28(金) 06:47:29
>>383 なるほど、一旦、List を経由するんですね。
勉強になりました。それで行ってみます。
ソートがあるのにシャッフルができない。 自前でやるしかないのか・・・。ゲームつくりたいんだけどなー。 STLでできたことができないと、ムキィーー!ってなるな。。。 std::swapとかmaxとかminとかイテレータとかとかとか・・・・。ムキィー!!
5行もいらんじゃねぇかw
398 :
384 :2006/07/28(金) 21:38:26
助言ありがとうございます。 C++/CLIなので.Netのライブラリで統一したいとは思いましたが 現状回避方法がないのならあきらめてSTLのstringを使うことにします。
適材適所がC++/CLIの特色だと思うぞ
.NETだけにこだわるならC#やらVBやら使った方がよっぽどいいと思う。
しかし、今ではC++/CLIやればC#もVBもまったく要らんからなぁ
ふふふ、C++/CLI いけない娘だ(w
しかし、注意しないといつの間にかに糞重いコードに変身。
ボックス化はコストがかかるからなぁ。ループには使っちゃいかんよな
unsigned char buf[1024]; のようなバイト列にファイルから1024バイト読み込みたいのですが、 FileStream と BinaryReaderを使った場合、 for文で1バイトずつ読み込むしかないのでしょうか?
BinaryReader::ReadBytes(1024)じゃあかんの?
>>406 ありがとうございます、cli::arrayの使い方をもう少し調べてみます。
nVersion = *(int *)(buf + 16);
memcpy(szFileName, buf+24, 256);
みたいな事がなかなか出来なくて・・・
BinaryReader br(stream); array<Byte>^ arr = br.ReadBytes(1024); br.Close(); でしょ
あとは、MemoryStream をもう一度 BinaryReader に繋げてもいいけど、直接読んだら? String^ fileName = gcnew String(arr, 24, 256); で、文字列は作れるけど
>>409 ありがとうございます。
arrayだと過去の関数と互換性が無くて、BYTE *にしたかったのですが
これはStringなどのクラスにも言える事でしたね
頭を切り替えて、.NETの勉強をし直すことにします。
>>410 cli::arrayもpinすれば従来どおりの配列として扱えるはず。
くだらない質問なのですがC++/CLIとC#はどっちを覚えた方がいいですか? 現在のスキルはVC2003.netでネイティブ,MFCで開発ができる程度。 STLやらBoostが.Netでは使えないらしいんでC++系列にこだわる必要も ないかなと思い始めてる。
C++/CLIはC#を知らないとわかりにくそう
>>407 こういうのを見るたび C++ と CLI って食い合わせが悪いよなーと思う。
C#というよりも、C#を通じてCLIの概念を知っておくと良いという感じだな。
416 :
412 :2006/08/01(火) 23:52:14
なるほど・・。 ではまずはC#から入っていくことにします。thx
417 :
デフォルトの名無しさん :2006/08/07(月) 11:10:43
C++/CLIって関数が失敗したときに値を返すんじゃなくて例外を投げるみたいなんだけど 値を返すやり方は止めた方がいいの? DLL作ってるんだけど、VBとかで呼び出した時に例外を取れるのか心配なんだけど……
418 :
デフォルトの名無しさん :2006/08/07(月) 11:24:02
心配なら、DLL側の入り口関数において例外を catch して、VB側へエラー値を返すやりかたにすればOK。
419 :
デフォルトの名無しさん :2006/08/07(月) 11:32:49
燃料消費率を上げれば解決するんじゃないか。 WEB入れるとあっというまに燃料がなくなり、 BBBから前線まではスロットルを絞って巡航速度で飛ばないと到着前に燃料切れになるぐらいが良いな。
420 :
デフォルトの名無しさん :2006/08/07(月) 11:34:57
すまん、419は誤爆
ただの VB ってことは COM 経由だろ。 マネージドな例外なら CCW が頑張って HRESULT に変換してくれる。
423 :
デフォルトの名無しさん :2006/08/09(水) 16:32:02
自作DLL(example.dll)内のクラスに他のDLL(System.dll)のクラスから継承した クラスがあり、アプリケーションからそのクラスを使いたいのですがアセンブリ 宣言で #using <System.dll> #using <example.dll> と両方のアセンブリを宣言しないとC3624のコンパイルエラーが発生します。 アプリケーション内で、System.dllのクラスを直接使用している部分はない ので出切る事なら #using <example.dll> だけで済ませる方法はないかと考えているのですが。何か良い方法はないで しょうか?
425 :
デフォルトの名無しさん :2006/08/09(水) 20:21:06
.NETでいう「参照型」って、C++の参照となんか関係があるんですか? 参照っていうよりはポインタの使い方のように思えるのですが。
ガベージ・コレクト自動追尾参照だな
加算減算が出来ないところが大きいね。
>>425 .NETの参照型とC++の参照型には何の関係も無い。
C/C++のポインタが難しいというイメージから逃れるため、
C++以外の世界では、ポインタ演算の無いポインタのことを参照ということが多い。
.NET Frameworkの参照型もその実例の1つ。
参照はポインタ演算のないポインタじゃないぞ. その程度のものだったら、GCがコンパクションした瞬間に終る.
追跡だっけ?すまん、忘れていた。 でも、.NETに限らなければ参照即ち追跡するものではないだろ。
できればWEBの資料だけでC++/CLI勉強したかったんだが ロクなページがないので本屋に行ってきた しかし本屋にもC++/CLIの本はロクなのないのな 多少マシな感じのするのが2冊あったくらい 「これからはじめるVisualC++2005」とか言うやつ 2005とうたっているにもかかわらず、マネージドC++の解説が 半分以上を占めていて萎えた 古い規格の解説なんか正直いらないんだが・・・。それしかないから渋々買ったが。 なんかおすすめなC++/CLIの本ないですか?
432 :
431 :2006/08/10(木) 23:12:46
書いた人をけなすつもりは無いことを補足しておきます。 わりと好きな著者なので。
C# で作ったアセンブリと、C++/CLI で作ったアセンブリを それぞれお互いに対し参照設定すると、 C++/CLI 側で、 >コンパイルエラー C2011:'identifier' : 'type' 型の再定義 というのが出るんですが、これを回避する方法はないでしょうか?
ファイルから一行読込んで、任意の位置で切出して、配列に代入してコンソールに出力するというプログラムです。foo.txtから読込んだ一行目のデータの内容は下記の通りです \var_{\cd3__8/_4/2006_19:39:18.981_H__foo.c__03472_Weak_coverage:_a=147_c=0_n=0}arr[0] = buff->Substring(1, 3);ではvarが正しく表示されるのですが arr[1] = buff->Substring(7, 9);期待している表示はcd3なのですが意に反して\cd3__8/_4と出力します、 同様にarr[2] = buff->Substring(12, 20);期待は8/_4/2006なのですが、ここでもまた 8/_4/2006_19:39:18.9となります、解決方法を教えてもらえないでしょうか?以下ソースです #include "stdafx.h" using namespace System; using namespace System::IO; int main() { StreamReader^ sr = nullptr; try { array<String^>^ arr = gcnew array<String^>(3); sr = gcnew StreamReader(" C:\\foo.txt "); String^ buff = sr->ReadLine(); arr[0] = buff->Substring(1, 3); arr[1] = buff->Substring(7, 9); arr[2] = buff->Substring(12, 20); Console::WriteLine(buff); Console::WriteLine(arr[0]); Console::WriteLine(arr[1]); Console::WriteLine(arr[2]); } finally { if ( sr != nullptr ) { sr->Close(); } } }
すみません読みにくくて foo.txtの一行目のデータは下記の通りですが、_は実際には半角スペースです \var_{\cd3__8/_4/2006_19:39:18.981_H__foo.c__03472_Weak_coverage:_a=147_c=0_n=0}
MSDN でメソッドの仕様くらい見ろよ
インスタンスから部分文字列を取得します。この部分文字列は、指定した文字位置から開始し、指定した文字数の文字列です。 半角スペースはカウントしないってこと?
日本語が読めないのか?
すまん勘違いしてた
質問です。 数値を文字列に変換したいのですが、 int GetTime,SystemTime,EndTime; char *text; SystemTime = timeGetTime(); //何らかの処理 GetTime = timeGetTime(); EndTime = GetTime - SystemTime; _itoa_s(EndTime,(char *)text,65,10); これを実行するとエラーを吐いて落ちてしまいます。 どうすれば良いでしょうか。よろしくお願いします。
>>441 textがどこのメモリも指していないまま、textの指す先に書き込もうとしている。
率直にstd::stringなりSystem::Stringなりを使いなさい。
>>441 char text[65];
:
_itoa_s(EndTime,text,sizeif(text),10);
ありがとうございます。
>>443 sizeifというのはsizeofのことでしょうか。sizeifだとエラーが発生し、sizeofだと思っていたとおりの動作になりました。
つかもう CLI とは全く関係なくなってるな
>>444 俺は443ではないが、sizeofのはずだ。
typeifはtypeof のtypoね。すまそ。 CLIに重きを置けばこんなコードになるのかの。 System::Diagnostics::Stopwatch^ sw = System::Diagnostics::Stopwatch::StartNew(); /*何らかの処理 ex. */ System::Threading::Thread::CurrentThread->Sleep(3000); sw->Stop(); System::String^ s = sw->ElapsedMilliseconds.ToString(); C++/CLIはC++を一応理解してからはじめないとポインタや参照、インスタンスの後始末あたりが ぐちゃぐちゃになりそうな気がする。 できたらC#やVBで.NETのクラスライブラリの使い方にも慣れてからがいい。
using namespace を使おうよー。これじゃ見づらいよー。 /clr:pure ならポインタを含めたメモリ関連の知識は特に必要ないと思うけどね。 まあそれだと何故 C++/CLI なのかって話にまでなっちゃいそうだけど。
using namespaceよりも、using宣言とnamespaceの別名付けでいこうよ。 実験用プログラム以外ではそれでやっているよ、俺。
これからはじめるVisualC++2005 買って読み始めた。 頭に入りやすいように順番が工夫されて書かれているようだ。 MC++もからめて書いているのは、理解の一助になるしそれほど 悪く無いと思う。 とりあえず全部眺めてCLIの準備だけはしておこうと思って。 仕事で使う日が来るのだろうか…
あれだね、漏れはその本買おうか迷ったけど
「実践C++/CLI極めるための基礎と実践テクニック」ていう本にした、
この本は
>>449 の本と逆で
普通VC8のインスコの方法から書くと思うのだが、そんなのは後回しで
C++/CLIとは何か、から始まってるが、じっくりソースを入力して動かしていると
よく納得できる感じ。
また、この本はNative C++、マネージ拡張、C++/CLIと対比させて説明してるが
NativeのC++がしっかり理解できて入れば、マネージ拡張をスルーしてもCLIは
覚えれそうと思うのは、漏れの錯覚デツカ?
これからはじめるVisualC++2005にはExpressのCDが付いてたのが ちょっと買った動機だったりする。いやMSからすでに落として インストールしてるけど、なんとなく商売の仕方を学んだ気がした。
漏れも、日経ソフトウエア7月号のVisual C++ 2005 ExpressのCDに釣られて 買ったが、内容が良かったので定期購読シテマツ。
CLR の Windows フォーム アプリケーション内で FindWindowEx を呼んでいるんですが、 ビルドの際に、 未解決のトークン、未解決の外部シンボルというエラーで FindWindowEx が見つからないと言われてしまいます。 解決策しってる人いますか?
>>455 まず解決するために自分でやったことを列記してよ。
>455 MSDN読んで適切なライブラリをリンクしろよ
>>455 APIは確かにそのまま使えるが、ヘッダのインクルードとライブラリのリンクは
必要だぞ
やっべ、俺親切すぎ
459 :
431 :2006/08/21(月) 00:41:53
これからはじめるVisualC++2005を一通り読み終わったが 450のいうようにそんなに悪くはなかった印象。 結局C++/CLIといっても通常の使い方をする上では それほどたくさん勉強するべきことはないな COMなんか覚えて時と比べたら、C++/CLIは甘いわ
質問です。「これから〜」で配列は、 array<int>^ ary = gcnew 〜; array<T^> var = gcnew 〜; みたいに解説があったけど、プリミティブじゃない方は ハットが足りなくない?(array<T^>^ じゃなくていいの?) 各要素がTの参照なのはいいとして、varはarrayオブジェクト の参照じゃなくても良いんだろうか? あと、intはSystem::Int32の別名だとあったけど、 int a; int *p = &a; はまずくないのかな? System::Int32は名前からしてランタイム管理下 にある構造体みたいなのに、アンマネージ型のポインタに受けちゃって 平気なのか? これが駄目だと既存のソースが軒並み通らなくなるので いいことになってるんだろうけど、腑に落ちないっす。
>>460 array<T ^ >^ が正しい。前後を見ないとわからなけど、その解説の方が間違ってると思う。
int *p = &a;
p はアンマネージ型のポインタじゃなくてunsafeなポインタ。/clr:safeだとエラーになる。
>>461 ども。
本の間違え、でスッキリしました。
>unsafeなポインタ
まだこれが理解できるレベルに達してないです。
もうちょっと読み進めてみます。
>>460 int/System::Int32に限らず、値型(value class/struct)のローカル変数はみな、
ローカルなスタック上に実体があるから、ポインタを追跡する必要が無いので
アドレス演算子を適用した結果はそのようにアンマネージポインタ型になる。
pureなclrでは従来のポインタは使ってはいけない、という解釈でOKですか?
>>464 混合とpureではOK, safeでは不可。
interior_ptr<T>を使えばポインタの使える範囲が広がる。それでもsafeではポインタの加算減算は出来ない。
ref struct V {int x, int y};
//
V^ v = gcnew V(); v.x = 10; v.y = 20;
int *p = &v.x; // error
interior_ptr<int> p = &v.x; // ok
array<String ^>^ ar = {"blue", "red", "green", "yellow"};
interior_ptr<String ^> p = &ar[0];
Console::WriteLine(*p);Console::WriteLine(*(p+1));Console::WriteLine(p[2]); p++; Console::WriteLine(*p);
>>465 ポインタの加減算したければpure使えってことですか。了解です。
ということは、従来のポインタ演算のソースをコンパイルしても
ネイティブコードは生成されないということですよね。
ネイティブコードが生成されない、従来のC/C++の書き方の範囲が
どのくらいなのかが気になるところです。
それが分れば、CLI、ネイティブ上でソース互換なプログラムが
書けそうですが…、
警告を見てると、__asm は当然として、可変引数を使うとvarargに対して
「ネイティブ コードの生成が発生します」と表示されます。
ネイティブ無しの可変引数のサブルーチンは書けないのでしょうか?
>>467 ありがとうございます。
標準Cの可変引数の書き方ではネイティブなコードの生成は避けられない
ということですか…。
CLIって、標準C/C++で記述されるプログラムの変換結果(というか構造概念)
を100%乗せられるような仮想マシンじゃないってことなのかな。
完全にCLIの上に乗っかったstdio周りとか、一番下位の入出力だけ.NETに
書き換えれば、ソースからコンパイルしなおすことで作れるかな、と思った
んですが。
>>469 へー、情報ども。ちうことはCランタイム呼び出しではマネージ←→ネイティブの
切り替えによるパフォーマンスダウンは無い、ということなんすかね?
/clr , /clr:pureともにmsvcm80.dllに関連付けられてるみたいだけど。
おれの可変引数サブルーチンもCLI上に乗っけたいよ…
そもそも可変引数は型が確定しないから安全ではないという理由でCLIに載らなかった訳で、 作れば載るけど、ポリシーとして作らない、んじゃないの?
ちょっと思いついたんだけどこういうのはどうよ。コンパイルできるか試していないけど。 #ifdef __cplusplus_cli namespace my { typedef ::cli::interior_ptr<System::Object^> va_list; } #define MY_VARIANT_ARGS ... ::cli::array<::System::Object^>^ myVariantArgs #define MY_VA_START(ap, parmN) ((ap) = &myVariantArgs[0]) #define MY_VA_ARG(ap, type) (::cli::safe_cast<type>(myVariantArgs++)) #define MY_VA_END(ap) (static_cast<void>(0)) #define MY_VA_COPY(dest, src) ((dest) = (src)) #else #include <cstdarg> namespace my { using std::va_list; } #define MY_VARIANT_ARGS ... #define MY_VA_START va_start #define MY_VA_ARG va_arg #define MY_VA_END va_end #define MY_VA_COPY va_copy #endif
試してみたらこうなった。 /clr の場合可変引数を持つネイティブ関数になる。ネイティブ・マネージド両方から呼び出せる。 /clr:pure の場合可変引数を持つマネージド関数になる。C++/CLIのマネージドコードからのみ呼び出せる。 /clr:safe コンパイルできない。 stdarg.hの中を調べると /clr:pureの場合に特別の分岐が仕込んであった。 引数を別の型で読み出すなどイレギュラーな処理をした場合の結果が異なることがありえるようだ。
>>473 >stdarg.hの中を調べると
こちらはエクスプレスなんだけど、プラットフォームSDKのstdarg.hは
_M_CEEの分岐は見つかったが_M_CEE_PUREでの分岐は見つかりませんでした。
仮に混合でも可変引数周りに/clr:pureのケースを適応したら、自前のアプリ
で従来可変引数の書き方をもってCLI上に乗せられるってことですかね。
ってか、混合アプリであっても、マネージドの部分から呼び出す
CランタイムはCLI上のを使ってくれるほうがC++/CLIらしいと思う
んだけどなあ
>>473 間違い。
もう一度見てみたら、vadefs.hのva_listに_M_CEE_PUREの判定があった。
>>473 まあそのイレギュラーな処理はごく一部を除いて元から結果が未定義だから、
それで問題が起こっても、傍から見る分には、そんなコードを書くほうが悪いと思えるけどな。
これからはじめる〜、やっとこさ半分。 delegateやeventが出てきた辺りでの印象だけど、 良く使うパターンを言語仕様として取り込んだC++ って感じ。
俺の職場、いまだにVC6+MFCな環境なんだが いいかげんVS2005+WindowsFormな環境に移行したい・・。 おまえらどういう理由でVS2005移行を提案した? .netに拒否反応示してる上司が多くてラチがあかない
自分が上司になればOK
うちは解析や大容量データの処理、3D周りなんで、64bit 対応を機に移行する予定 Vista が出てくる時期に合わせるつもりではいるけど、面倒なので悩んでる(w
>>478 VC6がばぐばぐだということを示して、まずはVC8+MFCへというのはどう?
でもそうするとその後.NETへいかなければならないから2度手間か、すまん。
>>478 社内ツールならすごく便利、優位になるという点を
アピール。
べつに今まで作ったものが動かなくなるわけじゃ無し、
頭固い上司だな。
売り物なら客が買ってくれるものじゃないと。
.NET必須だとまだつらいだろ
あれだな、正直言って漏れはMFCよりC++/CLIの方が社内で使う程度のツールなら 実装の時間がだいぶ短縮したと思う、C#やVBのソースを少しいじることで 実現出来るからそれも魅力だね。
486 :
デフォルトの名無しさん :2006/08/27(日) 16:24:18
ちょっとだけいじってたんですが、疑問がでたので質問です。 C# はヘッダがいらない言語ですが、 C++/CLIもヘッダがなくても別のファイルに定義したクラスに アクセスできるんでしょうか? コンパイル時間を気にしないようになりたい・・。
488 :
デフォルトの名無しさん :2006/08/28(月) 00:38:52
>>487 ありがとうございます!
調べてみます。
489 :
デフォルトの名無しさん :2006/08/28(月) 00:45:01
C++/CLIってC#を固くなに拒む人用?
>>486 同時にコンパイルするグループ内ではヘッダーファイルのincludeは必要。
DLLに分ける場合はややこしい。
enum class, value class, ref class rc, interface class については不要。
#using か /FU でアセンブリを指定する。
それ以外のC++と共通する文法のクラスや関数、変数には必要。
ネイティブの場合と同じでImport Libを使用する。
491 :
デフォルトの名無しさん :2006/08/28(月) 14:01:17
>>489 C++覚えた人がわざわざC#覚えなおす必要ないからあるんじゃない?
>>450 の本が気になって今日、仕事帰りに
「これからはじめるVisualC++2005」買った
>>451 です
確かにいい本だね、引き出しが増えそうです
林 晴比古 明快入門 Visual C++ 2005 ビギナー編にしようか迷ったけど、MFCの章が結構多かった事と
林本の傾向だけど、初心者向けというか、初学向けの感が否めないんで今回はやめました
林さんの本では、「新・C言語入門 シニア編」には大変お世話になったんで、次の
明快入門 Visual Basic 2005 シニア編に期待します。
>>489 Win32 API のヘッダが C# に用意されたら C# でもいいよ
いちいち、PInvoke の宣言をコピペするのめんどくさすぎ.
嫌がらせとしか思えん.
.NET Framework 2.0 もまだ Win32 API の機能を網羅してないくせに...
>>494 pinvoke.net ってコピペ文字列検索するだけのところだと思ってたけど違った?
VisualStudioExpress C++ 2005で作ったexeファイルを配布するには、どうすればいいんでしょか? .netframework2は入っているマシンに配布するなら、 MFCの使用を「スタティックライブラリでMFCを使用する」にすればOKですかね?
あと、Sqrt関数使うには System::Math::Sqrt って書かなきゃならんのすか? #define SQRT(x) System::Math::Sqrt(x) って書く以外に、 何かイイ方法ないでしょうか。イッパイ出てくるので。
using System::Math::Sqrt;
>>498 namespace のところに書くんですよね?
ボクもそれでいけると思ったのですが
「System::Math::Sqrtは名前空間ではありません」なのですよ。
>>497 vcredist_x86.exe でどーだろ?
>>499 それは using namespace System::Math::Sqrt; と書いた時の話だろ。
namespaceは要らない。
>>501 using System::Math::Sqrt; ってどこに書けばいいんすか?
using namespace System; 後はMath::Sqrtでいいんじゃない?Mathは名前空間ではない(クラス名)なので、 using Math;とかusing namespace System::Math;はできません。
>>505 >後はMath::Sqrtでいいんじゃない
あ、やっぱりそこまでですか。ども。
#include <cmath>及びusing std::sqrt;を書いて、sqrtを使うという手もある。 タイプ数削減のためだけにわざわざ使うのもどうかとは思うが。 (.NETバリバリのコードの中でこれだけCRTだと異質に見えるだろう)
マクロパワー万歳 #define sqrt System::Math::Sqrt いや、正直どうかとは思うのだけどC言語の標準ライブラリとCLIとの妥協点に思えて仕方がないんだ
よっぽど大量にSqrtを呼ぶなら、俺の場合きちんとインライン関数にする。 inline double sqrt(double x) { return System::Math::Sqrt(x); }
>>509 あーそれが一番良さそうですね。どうも。
納得すんのかよ!
513 :
デフォルトの名無しさん :2006/08/31(木) 22:29:20
template < MyEnum e > void Test() { if(e & MyEnum::b){ } } error C3063: 演算子 '&': すべてのオペランドには、同じ列挙型を指定しなければなりません というエラーが出るのですが、何がいけないのでしょうか? const MyEnum e; if(e & MyEnum::b){ } でも同様でした。
>>513 列挙子同士をビット演算することはできない。
なお、標準C++ではそのようなコードが書けるが、
それは演算子の両側をintに格上げして演算する規則になっているから。
C++のネイティブな列挙型では、自分でoperator &を定義しろというところだが、
CLIの列挙型では、Flags属性を付けたらいいと思う。
違っていたらすまん。
515 :
513 :2006/09/01(金) 01:26:51
enum struct MyEnum {zero,a,b}; if( (e & MyEnum::b) != MyEnum::zero){ } でも eがconst属性だと514のエラーになるみたいです。 if( ((MyEnum)e & MyEnum::b) != MyEnum::zero){ } なら通りました...
[System::Flags] enum struct MyEnum {zero, a, b};
/clrつけてコンパイルしたら、ネイティブのDebugビルドより 実行速度遅いの何とかしてくれ
マジかw ちょっと面白いな、それは。 笑い事じゃないが。
VS2005のC++/CLIでフォームアプリケーションを作成中のCLI初心者です。 単純化すると、このアプリでは以下の様な形で、FormAから同一フォームを クリックイベントなどで多重にモードレスで何回も呼び出す必要があります。 class FormA { ...... private: button_Click (System::Object^ sender, System::EventArgs^ e) { FormA^ ver = gcnew FormA(); // 同一フォームの多重呼出 ver->Show(); // モードレス } ...... }; スケルトンとしては動くのですが、実際には各々のFormAのプロパティにアクセスして (特にLocationやSizeプロパティなど)を変える必要があります。 これらプロパティのスタックはどこにあり、どのようすればアクセスできるのでしょうか? 上司がGUIアプリの実装時間節約になると、.NETが大好きなのでC++/CLIの採用は 要求仕様のため変えられません。まだCLIの情報が少なく、困っています。 MSDNのどこを読めとか、何でも結構ですのでアドバイスをお願いします。
>>519 フォームをリスト状に管理するか、単一のコレクションで管理するかわからないが、
単一コレクションならApplication.OpenFormsでもなんとかなるかな。
>>520 アドバイス、ありがとうございました。早速調べてみました。
単一のコレクションで管理しますので、
まさにApplication.OpenFormsを使えば何とかなります。
いやー、本当に助かりました。
SoapFormatterにStringReader,StringWriter渡せないのはなぜ? .NETのストリームにStringStreamがないのも奇妙なんだけども Stringがnon-mutating typeだからなのかな...
目的は飽くまで SOAP の為なのでバイナリ(=エンコーディング決め撃ち)じゃないと駄目だから。
524 :
デフォルトの名無しさん :2006/09/13(水) 23:00:38
VC++2005CLIにて、 タイマーイベントが発生するたびに、BinaryReaderのReadBytesメソッドで 一度に1Mバイトのデータを読む処理を行う、PF使用量どんどん増えて しばらくすると、OutOfMemoryExceptionの例外が発生してしまいました。 いろいろ試したところ、ReadBytesメソッドで一度に読むファイルサイズを10kとかにして タイマーイベント内で100回繰り返し読む(結果的に一度のイベントで読み取るサイズは同じ) ようにすると、この例外は発生しません。 これってどういうことか説明できるかた教えてください。
525 :
524 :2006/09/13(水) 23:02:12
すみません。 一度に1Mバイトのデータを読む処理を行う、 ↓ 一度に1Mバイトのデータを読む処理を行うと、 でした。
SoapFormatterでテンプレートクラスのシリアライズができなかったのですが、 タグに型名を記述できないのが原因?
String ^s って、動的に領域確保してくれるの? たとえば String ^s for (int i=1;i<=1000000000 ;i++){ s += Convert::ToString(i); } とかやってもダイジョウブ?
530 :
529 :2006/09/14(木) 11:24:51
実践C++/CLIの場合は、C#などで呼び出せるようにするためにラッパークラス を作っているのですね。 結局MFCコードは、コンパイルモードが混合(/clr)であれば、ほぼ そのまま.NETのコードにできるのですね。 この場合は、/clr:pureにはできず、64ビットでは動作しない と言うことになるのでしょうか?
>>527 それは平気だけど、そういう風に文字列をどんどん書き換えていくときにはStringBuilderの方が効率が良い。
System::Stringは一度作られたインスタンスの内容は不変なので、
そのように書き換える操作をする場合、実際には新たなメモリを確保しなおしている。
StringWriter でもいいんでない?
Writer は Builder を元に作るわけだから。
アプリ本体(exe)は/clrつければ混合でもとりあえず 共通言語ランタイムに乗っかりますが、dllも/clrつけ ればCLIになりますか?
なるけど、外部からアセンブリとしては参照できないだろ
C#で delegate void ProgressBarIncrementEvent(object sender,ref bool AbortFlg); これをC++に書き直すにはどうしたらいい? 特にref boolの意味が分からない、AbortFlgのポインターの参照のことかな・・・・?
delegate void ProgressBarIncrementEvent(Object^ sender, bool& AbortFlg) であかんの?
>>538 サンクス
public:
delegate void ProgressBarIncrementEvent(System::Object^ sender, bool& AbortFlg);
うっかりしてたpublic:書いてなかったんで変なことになってた
それから
ref boolはbool&でOK?
bool%ではだめデツカ?
ああ、むしろそっちのほうがいい気がする。
array<Byte> ^ Buffer = gcnew array<Byte>(1024); Bufferという1024バイトの配列に UInt16 bar = 0x55AA; という符号無の2バイトバイナリデータを一気に書込みたいのですがどのように書けば良いでしょうか? 教えて下さい。
1つ書き込みたいだけなら、 reinterpret_cast<UInt16%>(Buffer[0]) = bar; 本当に全部埋めたい場合、俺なら#include <algorithm>してstd::fillする。 pin_ptr<UInt16> ptr = reinterpret_cast<interior_ptr<UInt16> >(&Buffer[0]); std::fill<UInt16*>(ptr, ptr + Buffer->Length / sizeof UInt16, bar);
あのー、エラーでまくりなんですが(^^; : error C2275: 'System::Buffer' : この型は演算子として使用できません : error C2819: クラス 'System::Buffer' にはオーバーロードされたメンバ 'operator ->' がありません。 : error C2039: 'Length' : 'System::Buffer' のメンバではありません。
スマソ array<Byte> ^ Buffer = gcnew array<Byte>(1024); 書くの忘れてマスタ
>>542 最後にもう一つだけお願いします
アンマネージドの書き方教えてもらえませんか
タノンマス
#include <windows.h> //BYTE, UINT16 #include <algorithm> //std::fill BYTE Buffer[1024]; UINT16 bar = 0x55aa; reinterpret_cast<UINT16&>(Buffer[0]) = bar; UINT16* ptr = reinterpret_cast<UINT16*>(&Buffer[0]) std::fill(ptr, ptr + sizeof Buffer / sizeof UINT16, bar);
サンクス
.NETのバイトオーダーってどうなってるの?
CPU による
マジか!?CLIのくせして!
551 :
デフォルトの名無しさん :2006/09/24(日) 22:29:08
他の板に質問した(取り消し済み)のですが、レスがなかったのでここで質問させていただきます。 VC++2005 CLIのFormアプリケーションにおいて、以下の位置に グローバル変数を定義し、Formクラス内で使用すると、 値の設定、参照は正常にされているようですが、値のウォッチを するとスコープ外とでてしまいまい、不便です。 開発環境のオプションを変更するなどして見ることはできない ものでしょうか。それとも開発環境のバグなのでしょうか。 あと、構造体を定義し、コード内で使用するとメンバの候補 がでましたが、やはり値のウォッチはできませんでした。 #pragma once <ここに変数を定義> namespace ping_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; using namespace System::Net::NetworkInformation; using namespace System::Diagnostics;
バイトオーダーにCPUの個体差あったらイヤだな、と、ふと思った。
改行コードには環境による差がなかったか? ま、ドトネトはウイソばかりなので良いが。
昔のプリンタじゃないんだから、いーかげん\rは付けない様にして欲しいよな。 まあ、最近じゃ大抵無くても問題ないんだけどさ。
>>553 一応System.Environment.NewLineというものがある。
C++のソースを100%の.NETに置き換えようと考えています。 そもそも、/clr:safeでは、従来のnewは使用できないのでしょうか? 解説を読むとそうらしいんですが、これだとかなりの手間になりそうです。 後、C++のソースをC++/CLIのソースに変換するプログラムは無いですよね?
64ビットOSでネイティブに動作させたいので/clr:safeで無いと駄目です。 先に作業を始めてる人が居るんだけど全くビルドできてないのかな・・・ まずいなこりゃ
/clr:pureでもネイティブコードは一切含まれないから"pure"なんだが。
64ビットCLRでWOW64無しで動作するかと言うことをネイティブと言ってしまいました、 MSDNでもいまいちはっきりしないので、動かして確認してみるつもりです。
.NETの難読化って標準でついてこないの?
562 :
デフォルトの名無しさん :2006/09/25(月) 23:32:06
初めまして、インターネットを通じる以外にコンパイラー等を 手に入れる方法はございませんか?? 参考書等についていたりしませんか?? そういった参考書をお知りでしたら、教えてください。どうかお願いします。
>>560 /clr ネイティブとマネージド相互で呼び出しが出来る。
/clr:pure マネージドからネイティブが呼び出し出来る。
この2つはCランタイム(CRT)のネイティブコードを使用するため、必ずプラットフォーム依存になる。
/clr:safe ネイティブの呼び出しは出来ない。(DllImportを除く)
プラットフォーム依存なし。Cランタイム(CRT)が使えないため。printf などが全滅。
マネージドタイプのclassは使用不可。
x64のクロスコンパイラ使ってソースだけ共通にしたほうが現実的かな。
>>561 機能は削ってあるがDotfuscatorがStandardから付いてくる。
565 :
デフォルトの名無しさん :2006/09/26(火) 08:02:27
メンバ関数へのポインタについてなんですが、 class CTest{ public: void Func(){} }; void (CTest::*p)(); p=CTest::Func; なら代入できるってことは分かるんですが、 void *p=CTest::Func; はコンパイル通りませんでした。 void *p=(void *)CTest::Func;もコンパイル通りませんでした。 void *p=reinterpret_cast< void* >(CTest::Func);もコンパイル通りませんでした。 void *型ってなんでも代入できるんではないんですか? 何が何でも void* 型に代入したいんです。
566 :
565 :2006/09/26(火) 08:09:34
ちなみにVC6.0です
ちなみにスレタイの「/CLI」には意味があります。
>>565 オブジェクトへのポインタならどんなものでもvoid*へ変換できる。
逆に言えばオブジェクトへのポインタでないものは変換できない。
まず関数はオブジェクトではないので、関数へのポインタは無理だ。
(実装上できるようになっていることも多いしVCもそうだが)
そしてメンバへのポインタは、そもそもポインタとは異なる存在(概念として名前を借りただけ)
だから、void*へ変換できない。
そしてもっとも大事なことは、本来スレ違いであること。
そうそう、C++相談室へ具体的なコードを持ち込んでいけば、 色々と代案を考えてくれると思うよ。 ただしテンプレートを酷使するのでVC++ 6では厳しいだろうが。
570 :
565 :2006/09/26(火) 10:02:11
すいません、/CLI 自体知りませんでした。 CLIをCommand Line Interfase==Dos窓 != Windowsプログラミング だと勝手に解釈してました。 自分の無知さに涙がでました。 それにもかかわらず、アドバイスして下さった皆様、有難うございました。
571 :
556 :2006/09/26(火) 10:46:53
動かして確認したところ、/clr:pureの64ビット版でコンパイルすれば、 64ビットCLRでそのまま動作するようです。32ビット版では駄目ですが。 /clr:safeでなくてもOKてことですね。
>>570 C++/CLI (Common Language Infrastructure)
CLI (Command Line Interface) = CUI (Character User Interface)
ISO SQL/CLI (Call Level Interface) ≒ ODBC (Open Data Base Connectivity)
CLIと言っても色々あるからね〜
文脈がないとどれか判断は付かない。
ま、このスレを少し見ればCUIの事じゃ無いって事はわかるが。
VC++ 2005 に VC#.netのソースを移行しています(個人の趣味) VC#で外部に参照設定した関数の呼び出しで引数にoutを付けないとエラーになる部分があります。 COM名(引数1,out 引数2,out 引数3) VC++ 2005ではどうすればいいのですか。 引数1は数値型のenumで、引数2、3は文字列の配列です。 VC++2500のエラーメッセージ 「Safe Array は、0以外の下限または複数の次元を含んでいるため、この配列型にマーシャリングできません。」
Safe Array...? C++/CLI を使って、その COM のマネージドラッパ DLL を参照してる、んではない?
いやマーシャリングって出るってのはやっぱり C++/CLI だよな。 取りあえず情報が足りてない。 % 付ければ良いだけのような気もするが。
>>574-575 情報が足りてないのはその通りで、あまりに個別的なことを羅列しても
申し訳ないと思ったが、遠慮無しに披露すると
(1)メーカーのサイト
http://www.panrolling.com/pansoft/chtgal/ (2)ヘルプの抜粋
AllNamesメソッド (Namesクラス)
形式
Sub AllNames(ByVal Kind As KindFlag, Codes() As String, Names() As String)
Enum KindFlag
AM_KINDFLAG_SPOTS = 1
AM_KINDFLAG_FUTURES = 2
AM_KINDFLAG_ALL = 3
End Enum
VBでの例
次のコードは、データベースにあるすべての現物銘柄のコードと名前を文字列配列C、Nにそれぞれ読み込みます。
Dim Names As New ActiveMarket.Names
Dim C() As String, N() As String
Names.AllNames AM_KINDFLAG_SPOTS, C, N
(3)動いてるC#のソースの一部 Array aCode = new string[5000]; Array aName = new string[5000]; amName.AllNames(ActiveMarket._KindFlag.AM_KINDFLAG_SPOTS ,out aCode,out aName); (4)まだ動かないC++2005EEのソース cli::array<String^>^ aCode = gcnew array<String^>(5000); cli::array<String^>^ aName = gcnew array<String^>(5000); amName->AllNames(ActiveMarket::_KindFlag::AM_KINDFLAG_SPOTS,aCode,aName);
out引数は、呼び出すときなら特に何もする必要は無いはず。単なる参照扱い。 (out引数を取る関数を作るときにはOut属性を付けるのだが) んでout引数なんだからnewやらgcnewやらをするのは無意味だと思わないのか?
>>578 配列宣言を
cli::array<String^>^ aCode;
にしても同じメッセージの実行エラーが出ます。
「Safe Array は、0以外の下限または複数の次元を含んでいるため、この配列型にマーシャリングできません。」
だから、配列の基底を変えればいいのだろうか。
そもそもの関数定義を見せてくれんと悩んでいるところがわからん % つけるだけなんじゃね?
>>580 忘れていました
ActiveMarket::Names^ amName = gcnew ActiveMarket::Names();
です。
呼び出し部分を
amName->AllNames(ActiveMarket::_KindFlag::AM_KINDFLAG_SPOTS,%aCode,%aName);
にするとコンパイルエラーになります。
[Runtime::InteropServices::Out] ↑ こういうのは付けなくていいの?
>583 それは宣言のときに要るだけで、実際に呼び出すときには要らない。 >582 それはおかしい。構文上は元の書き方で良い。
>>582 ご教示ありがとうございます。実のところ#importというのもわかりません。
入門書に載っている引数を使った簡単なプログラムで #include <stdio.h> void sum(int x, int y); int main(void) { sum(1, 9); sum(9, 6); sum(81, 9); return 0; } void sum(int x, int y) [ printf("%d ", x + y); //←16行目ココ } の16行目でエラーが出てしまいます。 Cygwinとgcc使用ですが文字化けしていてエラーの内容がわかりません。 何が間違っているかわかりません助言よろしくお願いします。
本当にくだらなかったです。 15行目の「{」が「[」になっていたみたいです。 失礼しました。
589 :
デフォルトの名無しさん :2006/10/10(火) 07:59:27
string^ baka の^の意味を教えてちょ
592 :
デフォルトの名無しさん :2006/10/11(水) 07:02:16
ビット演算ってどういう意味? どういう時に必要なの? そもそもビットとは!?
最後の1問が致命的
教えられる地震がない
595 :
デフォルトの名無しさん :2006/10/11(水) 12:49:47
文字列の数字を数値に変える関数を教えてください。 ちなみにVC++2005です。
int.Parse
597 :
デフォルトの名無しさん :2006/10/11(水) 13:03:39
598 :
デフォルトの名無しさん :2006/10/11(水) 13:08:58
関数名からヘッダファイル名を知る方法はどうしたらよいのでしょうか?
>>597 System::String^ s = "123";
int::Parse(s);
const char*, const wchar_t*ならアンマネージの方法が楽だと思う。
>>598 MSDNなんかで関数名を引く。
const char* にせよ const wchar_t* にせよ gcnew String で String^ 作れるから、 そんな手間でもない。
それよりは、atoiなんかの方がタイプ数が少ないから、楽と書いた。 確かに手間でないと言われればそれまでだ。
そうか、C++ならatoiという手があったのか C#で駄目だったので心の中で禁じ手にしてた。
603 :
デフォルトの名無しさん :2006/10/12(木) 10:48:20
>>599 CP/M時代からの年寄りにはいろいろ覚えるのが苦手なので
変換には、なんでもかんでもConvert::を使っとるんじゃが、だめかのぉ
Convert::ToDouble
Convert::ToString
Convert::ToUInt64
なんでもそろっとるんで重宝しちょるんだがのぉ。ごほごほ
604 :
デフォルトの名無しさん :2006/10/14(土) 08:24:23
>>603 統一感があっていい関数を教えてもらいました♪ありがとうでやんす。
統一感ならboost::lexical_castだろと言いたいが、 マネージ型に対して使うのが困難なのが残念。
似たような質問で恐縮ですが… ネイティブの型とマネージドな型を相互変換するにはどのようなコードを記述すればよいですか? int <----> System.Int32 など
プリミティブな数値型に関してはコードを書くまでもなく暗黙に変換してくれるはずだが
608 :
デフォルトの名無しさん :2006/10/15(日) 14:02:30
>>606 System.Runtime.InteropServices
>>606 intとSystem.Int32は全く同一の型。単なる別名扱い。
ポインタや配列だとやや面倒。
何処かオライリーみたいなとこがリファレンス本とか作ってくれんかのぅ ヘルプ使うと普通にMFCのクラスとかでてきてやり難いったらありゃしない 長い年月かけて向き合うにはいいのかも知れないけど
つ フィルタ条件
つ「 」ってのは知的障害か釣りかという気がしてならない
スコープ外れるとDispose呼ばれるけどgcnewしたのは呼ばれないとか ごちゃごちゃあってよく分からないんですが。 C#の using(Pen p = new Pen(Color.Black)) { ・・・ } みたいな構文は try-finally でくくって delete するしかないんですか?
>>614 usingってスコープ外れるとDisposeされるだろう。
>>615 えっとじゃあC++/CLIでは
void Hoge()
{
ごめんなさい途中で送信しちゃいました えっとじゃあC++/CLIでは void Hoge() { Pen^ p = gcnew Pen(Color.Black); } ←ここで p->Dispose() が呼ばれる ということでいいんですか?
C++/CLIはデストラクタを使ってusingの代わりにする
>>617 void Hoge()
{
Pen^ p = gcnew Pen(Color.Black);
} ←ここで p->Dispose() は呼ばれない
void Hoge()
{
Pen p(Color.Black);
} ←ここで p->Dispose() が呼ばれる
そうだなC++/CLIは厳密にはC#のusingに相当する物は無い。 だからtry 〜 finallyで自分でgcnewした物をDisposeしておくのがいいかもしれん。
一応これで C# の using と等価のはずだが { Pen^ p = %Pen(Color.Black); }
>>619-621 なるほどありがとうございます。
C#の癖でそういう書き方出来ることすっかり忘れてました。
どっか、C++/CLIを C++でラップするようなサンプルサイト無いかな。 C++/CLIは出来るだけ避けないとヤバイ。
>C++/CLIを C++でラップ いやほらその、明らかに話の順序おかしくね???
おかしくねーよ。C++/CLIは C++の上位だけど、退化してるからな。 出来るだけ使わないに越したことはない。 ISOにも採用されてないし。
自分は共通部分をマクロで記述して C++とC++/CLI(safe)を切り替えられるようにしてるけどな。 でも既存のライブラリはそのままでは使えないからすごい面倒なんだよな...
>>623 #importなどを使ってCOM経由で使うというのはどう?
アンマネージドなVC++でやれるよ。
>上位だけど、退化してるからな。 その前提が既におかしいと思うんだが、finalyとか無いのどうしてんだ。 ハンドル型は全部テンプレートでラップしてんのか。 そもそもCLI使うなよくらいの話だと思うんだが、どーなのよ。
STL/CLRにはiteratorあるの?
>そもそもCLI使うなよ もう、それだけで致命的。
631 :
デフォルトの名無しさん :2006/11/14(火) 09:17:14
VC++/CLIで作成したクラスライブラリのメモリーリークのテストをしようとしたんですけど、 使用メモリー量が増えている原因がガーベージコレクション待ちなのか、本当にメモリー リークなのか良くわかりません。 確認のために、gcnewで確保したインスタンスを個別に解放したいんですが、普通に deleteを呼び出して解放すれば良いんでしょうか? 他にメモリーリークのデバッグでよい方法をご存知の方がいましたら、ご教示くださると 嬉しいです。よろしくお願いします。
GC.Collect
gcnewしたオブジェクトに対して、deleteを呼んでもデストラクタが呼ばれるだけ。
C++ガウス関数作れって言われたんだけど、渡された本は読んだんだけど おすすめな初心者解説サイトないですぁ?
質問を取り消します。
Stringが4個はいる配列はどうやって定義しますか? まだインスタンスは生成できないのでgcnew 〜使わない方法で
array<String^>^ a = nullptr;
4個はどこへ?
CLIを知らない俺が言うのもなんだが、 arrayって可変長配列なんじゃね?
動的固定長配列、と言う分類になるかな。 array<String^>^ a = gcnew array<String^>(4);
あー、array自身はgcnewしてもいいってことだったのか
クラスのメンバじゃないか?
F1押してもほとんど見つからないのはオンラインだから? MSDNインストールすればいけるの?
池沼は無視しとけ
>621 面白いと思ったんで試してみたら、 DbDataReader^ TestClass::TestCode() { // 接続作成 DbConnection^ connection = %OracleConnection("User ID=;Password=;Data Source="); // ステートメントの作成 DbCommand^ command = connection->CreateCommand(); command->CommandText = "SELECT * FROM TABLE WHERE FIELD1=1"; // OracleDBに接続 connection->Open(); // 取得する return command->ExecuteReader(); } MSIL上ではさっさとDisposeが呼ばれてしまいました。(´・ω・`)
ちなみにRedlector(C#)による出力結果。(MSIL付けても読みにくいと思うので・・・) private DbDataReader TestCode() { OracleConnection connection1; DbCommand command1 = null; DbConnection connection2 = null; OracleConnection modopt(IsConst) local1 = (OracleConnection modopt(IsConst)) new OracleConnection("User ID=;Password=;Data Source="); try { connection1 = local1; connection2 = connection1; } fault { connection1.Dispose(); } connection1.Dispose(); command1 = connection2.CreateCommand(); command1.CommandText = "SELECT * FROM TABLE WHERE FIELD1=1"; connection2.Open(); return command1.ExecuteReader(); }
で結局、抽象クラスで作りたい時は gcnew + try〜finally + delete するしかないんですかねぇ?
素のC++でも同じことではないのか?
>> 648 C# の using() {} 構文に匹敵できる事を期待していたのですが、 確かにManagedじゃないC++とかVB.NETとかJavaと同じだと言われれば、それまでの話です。 あと、 Class1 c1; Class2^ c2 = c1.getClass2(); try { // 処理 } finally { delete c2; } とか書くと、正常ケースの時に c1→c2の順にdisposeされてしまうみたい?です。 結局、このC++/CLIのDisposeパターン?はあくまで限定的な状況でのみ使える特殊技で、 基本は旧来の gcnew + try〜finally + delete だと思っておいた方が良いって事でしょうかね?
651 :
650 :2006/11/30(木) 18:31:49
失礼、1行抜けてました。 Class1 c1; Class2^ c2 = c1.getClass2(); try { // 処理 return; //<-ぬけてました。 } finally { delete c2; } もちろん、途中でreturnするのが行儀悪ですが、知らないとハマりそうかなと。
boost::scoped_ptrのマネージ版みたいなテンプレート作ってやるとどうだろう?
>>652 ttp://www.microsoft.com/japan/msdn/vs05/visualc/VS05Cplus.aspx の「リソース管理」にも
> しかし、単純な Using テンプレート クラスを作成し〜
とあって、気にはなってたのですが、こんな感じなのでしょうかね?
template<typename T>
ref struct Using
{
Using(T^ s) : p(s) {}
~Using() { delete p; }
operator T^() { return p; }
T^ operator ->() { return p; }
static T% operator *(Using% u) { return *(u.p); }
private:
T^ p;
};
ILを見ましたが、一応それらしく動いてはいるような気はします。
が、私は C++ と template についてはミジンコなのでイマイチ自信が・・・。orz
#スマートポインタという物の存在を3時間前に知りました。
そんな感じ。でもそのstruct Using自体はvalueでいいと思う。
>>654 値型の事だと思って単純に ref → value としたのですが
> 値型に既定のインスタンス コンストラクタ、デストラクタ、コピー コンストラクタなどの関数を含めることはできません。
と怒られてしまいました。
私は勘違いしてるのでしょうか?
すまん、そのことすっかり忘れていた。
>>656 やはり無理なんですね。勉強になります。
別案として、結局は常にハンドルが相手ですし、
またIDisposable.Disposeを呼びたいというだけなので、
generic という手もアリ?
generic<typename T>
ref struct Using
{
Using(IDisposable^ s) : p(static_cast<T>(s)) {}
~Using() { delete p; }
operator T() { return p; }
T operator ->() { return p; }
private:
T p;
};
でも、この場合は*演算子をオーバーロードできないような気がしますけど。
更に極論を言ってしまえば、 ref struct Disposer { Disposer(IDisposable^ s) : p(s) {} ~Disposer() { delete p; } private: IDisposable^ p; }; として、 Class1^ class1 = Class1->CreateClass1(); Disposer dummy1(class1); として使うんでも一応、必要機能は満たせますね。 ソースは汚くなりますけど。 #逆に、ILの方は意外と綺麗だったりするけど。(try〜finallyよりは。) tenplate を使うか、generic を使うか、Disposerクラスを起こすかは局面しだいって所か。 もはやVB.NETですら導入されてる事ですし、C++/CLI にUsing構文(相当機能)を入れてもらえるのが パフォーマンス等の面でも一番良いのですけど、政治的に難しいのかな。 けど、ない物でもユーザーの工作で何とでもなっちゃうのが面白いと、ミジンコは思いました。<C++
ファイルを1行づつ読込みテキストボックスに出力したいのだけど 最後の行しか表示できないんだよね、テキストボックスのプロパティは multilineはtrue、ScrollBarsはVerticalに設定してるのだが他に 何か設定する部分ってあるのかな? コードは間違ってないと思うのだけど・・・・・
じゃあそのご自慢のコードを書いてくれ
>>660 自慢じゃぁないけどこんな感じです.配列処理がしたかったのでチト変わってますが
特別な事はやってないはずなのですが。
private: virtual System::Void toolStripButton1_Click(System::Object^ sender, System::EventArgs^ e) sealed
{
using ::System::Windows::Forms::DialogResult;
OpenFileDialog^ openFileDialog1 = gcnew OpenFileDialog;
openFileDialog1->InitialDirectory = "C:\\";
openFileDialog1->Filter = "txt file(*.txt)|*.txt|全てのファイルAll files (*.*)|*.*";
openFileDialog1->FilterIndex = 2;
openFileDialog1->RestoreDirectory = true;
String^ line = "";
ArrayList al = gcnew ArrayList();
if ( openFileDialog1->ShowDialog() == DialogResult::OK )
{
String^ file = openFileDialog1->FileName;
IO::StreamReader^ sr = gcnew IO::StreamReader(IO::File::OpenRead(file));
while ((line = sr->ReadLine()) != nullptr)
{
al.Add(line);
}
for (int i = 0; i < al.Count; i++)
{
textBox1->Text = Convert::ToString(al[i] + "\r\n");
}
sr->Close();
}
}
textBox1->Text に代入してるんだろ? プログラム通り動いてるじゃん
えぇ・・・・確かに動いていますが、先にも書きましたが 1行(最終行)しかテキストボックスに表示されないのですが・・・・・ やりたいことは、全行テキストボックスに表示したいんですが。
textBox1->Text じゃ分からんようだから String^ a で代用しようか。 for (int i = 0; i < al.Count; i++) { a = Convert::ToString(al[i] + "\r\n"); } さて、a は最終的にどうなるかね。
>>664 寝てもうた、目が覚めたら自己解決しました。
また寝ますオヤフミ
C++/CLIによるフォームアプリケーションの開発で、MFCのCStringクラスを使いたいのですが、 どうすればいいのでしょうか? #include <atlstr.h> を記述すると、 C3641エラー (/clr:pure または /clr:safe と共にコンパイルされた関数に対する呼び出し規約 '__stdcall ' が無効です) がたくさん出てしまいます。 このため、共通言語ランタイムサポートを、ただの /clr に変えてみたのですが、今度は C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\include\ocidl.h(8005) : error C2872: 'IServiceProvider' : あいまいなシンボルです。 'c:\program files\microsoft visual studio 8\vc\platformsdk\include\servprov.h(100) の可能性があります : IServiceProvider' または 'c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll : System::IServiceProvider' というようなエラーが出てしまいます。。。
using namespace System;の記述を消せ。 そういう曖昧さが発生するから、C++ではusingディレクティブの使用は昔から勧められていない。
>>666 ラッパークラスを作成しないとそのまんまじゃ使えないよ。
MFCでの開発で便利だった TRACE()って、もう使えないのかな?
671 :
デフォルトの名無しさん :2006/12/16(土) 19:02:06
CLRプロジェクトでWindowsフォームアプリケーションを 作成した場合、そのWindowのハンドルインスタンス(HINSTANCE)は どうすれば取得できますか? Win32APIアプリケーションでは、 WinMain関数の第一引数としてすでに与えられていますよね。
GetModuleHandle(0) <windows.h> ウィンドウが関連付けているものではなく、WinMainの引数で得るのと近い雰囲気(中身は同じだが)。 GetWindowInstance(ウィンドウハンドル) <windowsx.h> ウィンドウハンドルからそいつに関連付けられたインスタンスハンドルを取り出す。 GetWindowLongPtrのラッピング、HINSTANCEにキャスト済み。 using System::Reflection::Assembly; using System::Runtime::InteropServices::Marshall; static_cast<HINSTANCE>(Marshall::GetHINSTANCE( Assembly::GetEntryAssembly().GetModules()[0])).ToPointer()) せっかくなので.NET Frameworkから方法を探してみた。 GetHINSTANCEの引数に与えるモジュールオブジェクトを手に入れるまでが一苦労、その後キャストするのも一手間。
673 :
デフォルトの名無しさん :2006/12/16(土) 19:37:37
>>672 さっそく、ありがとうございます。
Win32APIも初心者なので、そういう関数があること知りませんでた。
助かります。
フォームの中で DialogResult dr; と書くとコンパイルエラーになるんです。 なんかproperty Form::DialogResultと勘違いしているみたいです。 C#ならちゃんと型だと解釈してくれるんですけど
前も話題になってたな 諦めれ
using System::Windows::Forms::DialogResult;はだめか?
おおー
初心者がよくやる間違いテンプレみたいなところないですか? たとえば自分はよくfor構文の@に「;」をつけてしまって それに気がつかず悩むことが多々ありました。
String^ hoge = ""; textBox1->Text = hoge; とすると、空行が出来てしまうのですが(改行が残る)、空行ではなく行自体を削除する場合 どう書けばいいデツカ?
nullptr 入れてみたら?
>>681 680ですが
それやるとコンパイルは通るが実行すると例外が発生します。
System.ArgumentNullException' のハンドルされていない例外が mscorlib.dll で発生しました。
追加情報: 値を Null にすることはできません。
680ですが補足です .NETの正規表現はperl5準拠ということなので perlではddで空白行が削除できるらしいのですが これを.net的に書くとどう書くのでしょうか if (str == ""){ str = Regex::Replace(str, "\\dd", " $& "); } これでは無理デスタ
いや、空文字列は空文字列だから。空白行とか無いから。 大体 680 の内容がさっぱり分からん。改行が残るって何? nullptr 入れても例外とかでないし。 ArgumentNullException が出た時のスタックトレースとかどうなってんの?
>>684 サンクス
というか御免なさい、文字出力の部分で空行だろうと、何でも\nを付加シテマスタ
そりゃあ全部改行が付くしだいでして・・・・・
今気づいた申し訳なかった、スマソ
今まで、クラスの概念やで勉強してきたのですが、実際どのような場面で使ったら 良いのか分かりませんでしたが、ようやく使う時が来ました、ところが下記のコードではローカル関数の定義が正しくありませんとでます MSDN見ても 関数内で関数の定義を試みました。 または、ソース コード内の C2601 エラー位置の前に、余分な中かっこが含まれている可能性があります。 何処が悪いのか教えてくださいませ。 オナガイシマス void Counter::countUp()←error C2601: 'Foo::Form1::Counter::countUp' : ローカル関数の定義が正しくありません。 { this->lineCounter++; } ref class Counter { private: int lineCounter; public: void countUp(); };
クラス定義の中で関数定義しちゃってる予感 ま、出てる内容だけじゃ断言できないけど。
>>687 どうも686です、頭パニクッってます
書き方的にはおかしくないと理解しても良いですか?
ただ
>>クラス定義の中で関数定義しちゃってる予感
何に着眼して問題点を探せば良いのでしょうか?
>ref class Counter >void Counter::countUp() クラスの宣言と実装の順番が逆とかいう話じゃないよな?
>>689 どうもです順番はForm1.hに下記のような順番で記述しています。
開始
#pragma once
namespace C_Laanguage_Analysis_Tool {
using namespace System;
using namespace System::Text;
using namespace System::IO;
省略
private: System::Void tabPage3_Click(System::Object^ sender, System::EventArgs^ e)
{
}
ref class Counter{
private:
int lineCounter;
public:
void countUp();
};
private: virtual System::Void toolStripButton1_Click(System::Object^ sender, System::EventArgs^ e) sealed
{
省略
void Counter::countUp(){
this->lineCounter++;
}
省略
}
以下自作の関数
};
}
終わり
tabPage3_Clickが、Counterのメンバなら、 ref class Counter{からそれに対応する};までの間に書け。 System::Voidは単にvoidで良い、ってIDEがSystem::Voidを出力するんだっけ。
これどう見ても toolStripButton1_Click の中で Counter::countUp 定義してるよね……
>>691 さんよろしくです
ref class Counter{
private:
int lineCounter;
public:
void countUp();
};
をいろんな処に書いてみたのですが、結果はNGです・・・・・どうしたらいいんだろう
#pragma region Windows Form Designer generated code
↑
いじったら怒られるところ
↓
#pragma endregion
←ここもだめ
private: Void toolTip1_Popup(System::Object^ sender, System::Windows::Forms::PopupEventArgs^ e){
}
←ここもだめ
private: Void tabPage1_Click(System::Object^ sender, System::EventArgs^ e){
}
←ここもだめ
private: Void tabPage3_Click(System::Object^ sender, System::EventArgs^ e){
}
←ここもだめ
private: virtual Void toolStripButton1_Click(System::Object^ sender, System::EventArgs^ e) sealed
{
一番下の「ここもだめ」の下にあるものはなんだ?
そこの下の中に、toolStripButton1を押下した後のメインプログラムを実装しています 具体的には、 openFileDialog1を開いてファイル選択してオープン 文字処理を施し テキストボックスに出力 ざっとこんな流れです 自前の関数はそのブロックの外に置いています。 こんな感じです。
ところで、692に書いてあることは読んだか?
気付きませんでした toolStripButton1_Click の中で Counter::countUp 定義したら駄目なんですか? ちょっと待って下さい外で定義してみます ref class Counterの位置は今のままでOKですよね・・・・?
素のC++のときから関数の中に関数を定義するのは不可能。
#pragma endregion ref class Counter { private: int lineCounter; public: void countUp(); }; void Counter::countUp() { this->lineCounter++; } private: virtual System::Void toolStripButton1_Click(System::Object^ sender, System::EventArgs^ e) sealed { こうしたら、コンパイラ エラー C3254 'explicit override' : クラスは明示的オーバーライド 'override' を含みますが、関数宣言を含むインターフェイスから派生していません。 メソッドを明示的にオーバーライドする場合、オーバーライドを含むクラスは、オーバーライドする関数を含む型から直接または間接的に派生する必要があります。 となりました、これってどう対処したらよいのでしょうか
お騒がせしました、ようやく目が覚めました 末尾に追加したらコンパイルは通りました、馬鹿者に付き合っていただき スンマセンでした。 感謝しております。
追伸 末尾では、だーれも認めてくれなかったので先頭で public: using namespace System; 省略 続きに書いたら、 Counter^ addition = gcnew Counter(); addition->lineCounter = 1; これもOKにナリマスタ、ようやくこれで宣言まではできました。
703 :
デフォルトの名無しさん :2006/12/27(水) 03:47:07
すいません、.NETの話しなんですけど(場違いだったら誘導してください)、 ウィザードから吐かれたmain内の↓部分で、 // メイン ウィンドウを作成して、実行します Application::Run(gcnew Form1()); フォームのイベントが無いときはずっと自前の処理をループさせて イベントがあったときだけフォームの処理をさせるようにしたいと思いまして、 以下のように改造しました。 Form1 frm = gcnew Form1(); frm.Show(); while(frm.Created) { 〜略(ココに好きな処理)〜 Application::DoEvents(); } そしてこれをコンパイルしたところ、 error C3673: 'test::Form1' : クラスはコピー コンストラクタを含んでいません と怒られました。 エラーの意味をマニュアルで調べましたがどういうことか良く分かりません。 正しくはどう書いたらよいか教えてください。
Form1 ^frm じゃねーの?
705 :
デフォルトの名無しさん :2006/12/27(水) 04:00:52
706 :
デフォルトの名無しさん :2006/12/28(木) 04:37:56
ここ何年もC++のWindowsプログラミングから全く離れていて、 Managed C++とかC++/CLIとかいう単語が出てきて浦島太郎状態なのですが、一つ質問を。 データ処理部は普通のC++でSQLiteを呼び出し、UI部は.NET Frameworkの機能を使いたいのですが、 C++/CLIを使うと両者は共存できるのでしょうか?
>>706 できるよ〜。
DLLだけでなくOBJ/LIB単位でもネイティブとマネージドを混在できるので、
よほどことをしてない限り問題なし。
マネージドからネイティブへの文字列の変換がちとめんどいだけ。逆方向は問題なし。
なるほど、ありがとうございます。
サブルーチンの中にサブルーチンを書くのはどうでしょうか? というのも指導教官に「それはよくない。美しくない」と指摘されたのですが、 実用性を重視するなら、ありといえばありですよね? みなさんが直面された重要な困難があれば教えて欲しいです。
C++/CLIと何の関係が?
すいません709は取り下げます 総合質問スレみたいなの探してるんだけど見つからないのです。
ローカルクラスでゴニョゴニョ…
714 :
デフォルトの名無しさん :2006/12/30(土) 13:17:24
char型の配列 のポインタ の配列 を宣言したいのですが、どう書くのでしょうか
つchar***
このスレ的にマネージ型では::cli::array<::cli::interior_ptr<::cli::array<char>>>
あけましておめでとうございます. C++/CLIでWindows Mobileの.NET Compact Framework用のアプリを作れますか? 開発環境はVisual Studio 2005で.
719 :
デフォルトの名無しさん :2007/01/03(水) 23:21:18
コンストラクタで質問っす CLIの問題というかC++の問題な気がするのだけど、C#なら public Hoge( int hoge ) {...} public Hoge() : this( 1234 ) {...} こんなんでコンストラクタの使い回しが出来るけれどC++/CLIだと無理ですか?
>>719 悪い、C#触ったことないから、何を意味してるのかわからない。
>>719 普通のC++では、その段階でオブジェクトの構築が終わっていない故に、
初期化リストでthisを使うのは未定義の振る舞いを生む。
>>720 C#では、あるコンストラクタから別のコンストラクタを呼び出すことが出来るんで、
こうするとデフォルトコンストラクタで1234と初期化できます
class Hoge
{
private m_hoge;
public Hoge( int hoge ) { m_hoge = hoge; }
public Hoge() : this(1234) {}
};
コードの重複を避けるために便利なだけですね。
重複を防ぐだけならprivateメンバ関数でも作って
そこで初期化すりゃいいじゃんって話ですが、なんとなく気になったので…
>>721 ここで使ってるthisは自分のクラスのコンストラクタという意味のthisで、
C++の自分自身のポインタという意味のthisとは別の意味なんです
(もちろんC#でもthisは自分自身を表すけれどこの場合は特別)
基底クラスはそんな感じで呼ぶけどな。
まあ
>>719 の用事なら
クラス定義で
Hoge( int hoge = 1234);
ができるけど。
>>723 CLIではref classの関数のデフォルト引数の設定が出来ないです。
別途インスタンス作成のための静的メンバ関数を設ければよい。 ref class Hoge { int m_hoge; public: //時と場合によってprotected或いはprivate Hoge(int hoge) : m_hoge(hoge) {} public: static Hoge^ CreateHoge(int hoge) {return gcnew Hoge(hoge);} static Hoge^ CreateHoge() {return gcnew Hoge(1234);} };
>>725 普通にインスタンス生成できないのは美しくないので…
流石にそこまで言うと贅沢ですかね。
結局、いつもネイティブC++でやってる
全コンストラクタで使うprivateメンバ関数を別に用意する方法にしました。
皆さん色々ご意見ありがとうございました。
デリゲート・コンストラクタは将来拡張予定
フォームアプリでウィザードが吐いたフォームのクラスですが、 public ref class Form1 : public System::Windows::Forms::Form これを継承して例えばMyAppとかいうクラスを作りたいんですけど どうやって書いたらよいですか? マネージは知らないので、今までネイティブクラスに gcroot<Form1^> m_frm; などとメンバに持たせてコントロール類にアクセスしたりしてましたけど 面倒になったので、素直に継承させるのが正しいかなと思いました。 あと、継承させるとなるとMyAppもマネージ型のクラスにする必要があると思いますが、 このクラスには普通のネイティブな型の変数とかをメンバに持たせられるのでしょうか?
public ref class MyAppForm : public Form1 でいいでしょ 普通のネイティブ場メンバは持てないが、ネイティブ側からマネージド・クラスを friend に 指定するなり、アクセサを用意するなりで、相互操作は簡単だ
ネイティブクラスへのポインタ型は持てるはず。 そもそもForm1自体をいじってはダメか?
IntPtr だな COM なら com::ptr だが
733 :
デフォルトの名無しさん :2007/01/06(土) 17:52:24
C++とC++/CLIは何が違うのでしょうか? それとC++が書けるのにわざわざC++/CLIで書くメリットとデメリットは何なのでしょうか? 素人的な質問ですがどうぞ宜しくお願いします
>>733 C++で.NETフレームワーク用のアプリケーションを記述するための拡張規格。
文法的にC++の上位互換になっている。
メリットはC#やVBなど他の.NETアプリケーションとの親和性が高く、
また.NETフレームワークの言語の中ではもっともネイティブAPIやライブラリとの相互運用性に優れている。
デメリットは.NETフレームワークが必要になること。
C++/CLIをサポートするコンパイラ(開発環境)にVisual C++2005がある。
これはネイティブと.NET(マネージド)の両用。初心者が知らずにC++/CLIを使ってしまうことがあり、
C++すれでスレ違いと怒られることが多々ある。
>>733 .NET Framework必要か、そうでないか。
っていえばわかりやすいのかな。
C++は特に何も入れなくても動くけど、
C++/CLIはランタイム必要。
.net使うのはC#で書いたほうがいいような気がするけど。
>>733 Java における JNI を .Net 用に構文として整理したもの
JVM の代わりに CLR をロードし、その上でいろいろとやる
737 :
デフォルトの名無しさん :2007/01/06(土) 18:54:37
今から、.NET Frameworkを含めてC++/CLIを勉強するのに良い書籍があったら教えてください。 C++はそれなりに経験があります(ここ何年かはJavaばっかりであんまり触ってませんが・・・)。
738 :
デフォルトの名無しさん :2007/01/07(日) 08:30:49
>>734 >>735 >>736 ありがとうございました。
ですが、C++/CLIはC#と同じくVM上で動かすことになるので
C++に比べて速度が落ちると思うのですが、大体どれ位落ちてしまうものなんでしょうか?
>>738 難しい質問だな。VC++2005Expressは無料で手に入るから自分で試してみるのがいい。
マネージドのグローバル変数というものが存在できないみたいなのですが、 皆さんは設定とかをグローバルに置きたい時はどうしていらっしゃいますか。 やはりSingletonパターン?
使わないに越したことはないが、どうしても使いたければ静的クラスの静的メンバ
>>738 それより、起動がすごく遅いっていうのがなぁ…
い
>>740 設定クラスを作ってインスタンスを持ちまわる。
決してグローバルに参照できるような変数には代入しない。
C# の partial class は C++/CLI にはありませんか? hoge.h partial ref class Hoge{ public: // ここには public 項目しか書きたくない } hoge.cpp partial ref class Hoge{ // hoge.h に書けなかったこと全部 } とかやりたい。 interface クラスは意味がないし。
partialはないけど、普通のC++のように、ヘッダに宣言だけしておいて、ソースファイルに定義を書けるはず。 //hoge.h ref class Hoge { public: void PublicFunc(); private void privateFunc(); }; //hoge.cpp #include <hoge.h> void Hoge::PublicFunc() { //... } void Hoge::privateFunc() { //... }
>>746 は、ヘッダだけ公開するからprivateを書きたくない、というような意味だと思う。
そこでpimplメソッドですよ
>748-749 thx!
あ、ミスった。747さんもありがと。
CLI準拠つまりC#やVBから呼び出せる形でDLLアセンブリを作ればヘッダーは公開する必要が無くなる。
CLIに準拠していなくてもref/valueやinterface/enum classあたりならなんでもいけるはず。 ところで、System::Runtime::CompilerServicesにIsLongとかIsConstとかあるんだね。
vs2005のC++/cliですが、 自動生成された雛形のForm1にデザイナでコントロールを配置して それぞれのイベントの処理関数を書いていたのですが Form1.hがどんどん肥大化して段々と見難くなって来ました。 そこで、機能のグループごとにForm1を継承したクラスFormを作り、 イベント処理関数(雷マークのところで追加したやつ)を オーバーライドすればいいのかと思ったんですけど どうやって書いたらいいのでしょうか? 例えばForm1.h内に追加されたイベント処理関数が private: System::Void numupdown_ValueChanged(System::Object^ sender, System::EventArgs^ e) {} であったとして、 これをForm2内でオーバーライドして内容を実装したいです。 具体的にどう書けばいいか教えてください。 あと、そもそもこういう時ってどうしたらいいんでしょうか? 継承して欲しいイベント処理関数だけオーバーライドするってのは正しいですか?
すいませんがageさせてください
そのイベントハンドラ内から仮想メソッドを呼ぶのがいいんじゃね
757 :
754 :2007/01/15(月) 22:20:48
>>756 すいませんがまだ不勉強なものでよく分かりません。
とりあえず下のように書いてみましたけど
public ref class Form2 : Form1
{
private: System::Void numupdown_ValueChanged(System::Object^ sender, System::EventArgs^ e) {
MessageBox::Show(""); }
};
ビルドは通るもののメッセージボックスは出てきてくれません。
正しくはどうやって書いたらいいでしょうか。
Form1 の方でVirtualを付けないと、イベントの登録はForm1のほうでやってるんだろ? private: virtual System::Void numupdown_ValueChanged(System::Object^ sender, System::EventArgs^ e) {}
VC6のコードを移植中にこのような文で _tcscpy(_tcsrchr(buffer, _TEXT('\\')) + 1, _TEXT(log)); warning C4996: 'strcpy' が古い形式として宣言されました。 とC4996に注意されたので、いつものごとく 返還前 _tcscpy ↓ 安全な型に変換 _tcscpy_s こうしたら、今度は error C2660: 'strcpy_s' : 関数に 2 個の引数を指定できません。 と本気で怒られました、どうしたらイイデツカ 教えて下さいエロイヒト
リファレンス見れ
>>759 そのソースが十分信頼にたるものなら警告は無視していい。警告を抑制したいならこれでコンパイル。
cl /D_CRT_SECURE_NO_DEPRECATE xxx.cpp
_tcscpy_sを使いたいならマニュアルを参照。バッファの最大サイズを指定する引数が増えてるはずだ。
762 :
754 :2007/01/15(月) 22:58:45
>>758 イベント処理関数のコントロールへの登録と宣言はForm1の方で
デザイナが勝手に吐いてくれた奴です。
で、教えていただいたとおりForm1の方の宣言の方にVirtualを付けてみたんですけど
なぜか反応してくれませんでした。
宣言にVirtualをつけて尚且つ派生クラスで実装してるわけですが、
コントロールへの登録の際は特別何か考慮せずにそのままで良いのですか?
763 :
754 :2007/01/15(月) 23:02:20
訂正 >コントロールへの登録の際は特別何か考慮せずにそのままで良いのですか? コントロールへ処理関数を登録している部分は特別何か考慮せずにそのままで良いのですか? ↓ココ this->numupdown->ValueChanged += gcnew System::EventHandler(this, &Form1::numupdown_ValueChanged);
>>761 サンクス
C2660
メンバ関数の呼び出し形式に合うように関数呼び出しを書き直します。
スコープ解決演算子 (::) を使用して、グローバルな名前空間で関数名を検索するようにコンパイラに通知します。
スコープ演算子はありえないと思っていたが、足らない引数が分からなかった
_tcscpy(_tcsrchr(buffer, _TEXT('\\')) + 1, ,sizeof(buffer) + 1, _TEXT(log));
これで幸せにナレマスタ
,が一個余分だったスマソこれが正解↓ _tcscpy_s(_tcsrchr(buffer, _TEXT('\\')) + 1,sizeof(buffer) + 1, _TEXT(log));
766 :
sein :2007/01/15(月) 23:24:23
>>762 おっとと、privateのままだった。
protected: virtual System::Void numupdown_ValueChanged(System::Object^ sender, System::EventArgs^ e) {}
継承したほうには override が必要なはず。
>>764-765 _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMESという手もある。
769 :
754 :2007/01/16(火) 00:02:43
>>767 //Form1.h
protected: virtual System::Void numupdown_ValueChanged(System::Object^ sender, System::EventArgs^ e) {}
//Form2.h
public ref class Form2 : Form1
{
protected: virtual System::Void numupdown_ValueChanged(System::Object^ sender, System::EventArgs^ e)
override { MessageBox::Show("");}
};
と書いてみましたがメッセージボックス出てくれないです。
なんで〜・・・orz
>>769 ref class では継承のデフォルトはpublicだから、
public ref class Form2 : public Form1 とやる必要はないはずだし、
まさかこういうところを間違ってるとかないよな?
Application::Run(gcnew Form1()) ・・・ Form2に変えてないとか
771 :
754 :2007/01/16(火) 00:37:50
//mainの中 Form1 ^frm = gcnew Form1(); frm->Show(); App* pApp = new App(); while(frm->Created) { Application::DoEvents(); } ////////////////////////////////////////// class App { private: gcroot<Form2^> m_frm2; public: App(); ~App(); void Init(); }; こんな感じでAppにメンバとしてForm2をもたせてgcnewしてるんですけど、 これでは呼ばれないんでしょうか? 実際に表示しているのはForm1なんですが、 Form1のイベント処理関数を Form2とかForm3とかいうクラスにグループごとにまとめてそっちで実装したいんです。 動機はForm1.hが肥大化してきて見辛いから、というだけなんですが。。。
.NET Framework的にはApplicationContextを継承したクラスをApplication.Runに渡すべきでは? Application::DoEvents()をループするよりも。
773 :
754 :2007/01/16(火) 01:52:02
>>772 DoEventでやってるのはゲームっぽいものを作ってるからなんですけど、
どちらにせよループまわしたりRunしたりするのは
Form1ではダメなんですか?
Form1から継承したクラスが複数あったら
どれを使ったらよいのでしょう?
というか、そもそもVSのCLIでちょっと大きいアプリを作るときって
皆さん普通はどうやって作るんですか?
Form1.hがどんどんでかくなっていくんですけど。。。
UIに関係のない処理は別のクラスに追い出してる?
775 :
754 :2007/01/16(火) 09:17:18
>>774 はい。771のAppってクラスはUI以外の処理を書いてます。
でもなんでできないんだろう・・・
そもそもの動機や解決のアプローチが間違ってるんだろうか。
ものすごく王道で当たり前のことと思ったんですけど、
そうじゃないんでしょうか。
怒られそうですが、
誰か同じことやって試してみてください・・・
と甘えてみる。
「C#のnetmodule」と「それを利用するC++のソース(C++/CLIでもManagedCでも構わない)」があります。 コンパイル時に生成ファイルに埋め込んでしまう事で、 実行時に「C#のnetmodule」の方を必要としない1個のDLLを作成する事は、 2003(.NET1.1)ではできるのでしょうか? ただし、C++のソースにはDLLエクスポートした関数を含めたいので、 alを使う方法は使えないと思ってます。(多分。) いちおう、2005(.NET2.0)では上記を満たす方法があるのは(C# と C++/CLI の組み合わせで)動作を確認しているのですが、 同じ方法を2003(C# と Managed C++)で試みると、リンカで > XXXX.netmodule : warning LNK4003: ライブラリの形式が無効です。ライブラリは無視されます。 と出て、実行時に「C#のnetmodule」を必要とするDLLが作成されてしまいました。 (´・ω・`)
777 :
デフォルトの名無しさん :2007/01/16(火) 11:01:08
摂氏温度(C)と華氏温度(F)は、次の式で変換できる。摂氏温度30度から、5度みに、105 度まで、それに対応する華氏温度を計算し, 下記のような対応表を作成しなさい。 F=5/9C+32.0 出力は、左右に2列に摂氏温度と華氏温度が{表}になるようにしなさい。 この問題が分からないのですが、よかったら誰か教えてくださいorz
778 :
754 :2007/01/16(火) 11:13:10
MSDNのc++フォーラムの方で聞いてみましたので、 もし返信いただける方はそちらでお願いします。
>>776 .netmoduleはマルチアセンブリのための仕掛けだから基本的に出来ない。
サードパーティのツールでマルチアセンブリを単一アセンブリにするものはあるらしいが標準ではない。
ところでマルチアセンブリを有効活用してる例というのはトンと見ないね。
780 :
デフォルトの名無しさん :2007/01/16(火) 14:46:46
>>777 >>780 どこでなにがどうC++/CLIと関係があるのか全然ワカランので、説明つけてください!
あともう少しなんとかなりませんか?
CLIの意味よく理解してませんでした; スレ違いみたいでしたスマソ
話には聞いてたけど、学校の課題を全部他人にやらせようとする奴って本当にいるんだな。
>>784 あっちでも似たような回答しか出ませんな。
継承の意味を間違って理解してるのがあれだね。
>>784 つか、ミスの内容が・・・(^^;
その辺りで単なる凡ミスじゃなく、それこそ学校の宿題を人にやらせようとしてる類と思われて適当に流されてるような。
数少ない回答も「子供に教える口調」になってるし。
>>779 やっぱりできませんか。現場じゃ使いにくいなぁ。(´・ω・`)
ちなみにマルチアセンブリを有効活用できるってどんな可能性が考えられるんでしょ?
私は今回のように違う言語を組み合わせる時、以外は思いつかないんですけど。
787 :
デフォルトの名無しさん :2007/01/18(木) 00:40:59
質問です。 VS2005 std でC++/CLI で、クラスを作っているのですが、 たとえば、こんなんでビルドすると、 ref class Test { virtual void test(void){;} }; warning C4486: ref クラスのプライベート仮想メソッドまたは値クラスは、'sealed' に設定されなければなりません という警告が出ます。 エラーではないのでそのまま実行できますが、気になります。 オーバーライドされる可能性があるから仮想メソッドにするのではないのでしょうか? なのにsealedに設定するってどういうことですか? また、sealed をつけたとしても、派生クラスを作ってオーバーライドすることも できてしまうようです。 何か思い違いをしているのでしょうか?
788 :
デフォルトの名無しさん :2007/01/18(木) 00:53:27
privateメンバだからでは? publicかprotectedじゃないと派生クラスから見えんでしょ。
ってことは無いみたいだな。
790 :
787 :2007/01/18(木) 01:24:54
ごめん、オーバーライドはできてなかった模様
791 :
787 :2007/01/18(木) 02:42:13
public ref class Test1 { virtual void test(void) {処理1;} public: virtual void CallTest(void){test();} }; public ref class Test2 : public Test1 { virtual void test(void) override {処理2;} //public: //virtual void CallTest(void) override {test();} }; で、以下を実行すると Test1^ test1 = gcnew Test1; Test2^ test2 = gcnew Test2; test1->CallTest(); test2->CallTest(); 結果はビルド時に警告、実行時エラーとなる そこで、Test2::test の "override" を取り除くと、 実行結果は 処理1 処理1 となって基底クラスのtest()が実行される この状態でTest2のコメントアウトを外すと 処理1 処理2 となる
792 :
787 :2007/01/18(木) 02:44:29
C#やmanaged C++でも試してみた C#・・・private のオーバーライドは不可 MC++・・・private のオーバーライドできる C++/CLIはC#のようにprivateオーバーライド不可ってこと? それって不便なことない?
C++のアバウトさも好きだけど、C#風ののやり方には一貫性があるし不便はないな。 ただ同じC++/CLIの中でref classと通常クラスで流儀が違ってくるのはいただけない感じ。 ところでMSDNの警告C4486にある「プライベート仮想関数 sealed の使い方の一例を次に示します。」 の部分のコードだけど誰か説明してくれ。さっぱりわからん。 ref class B {}; ref class D : B {}; interface class I { B^ mf(); }; ref class E : I { private: virtual B^ g() sealed = I::mf { return gcnew B; } public: virtual D^ mf() { return gcnew D; } };
privateは派生クラスからも隠匿されてるからこそのオーバーライド不可なんでしょ。
不便も何も、MC++がオーバーライド可能であることが「そんな馬鹿な」って感じだけど。
>>793 インターフェイスのメソッドのオーバーライドだから仮想でなくてはならない(だからvirtual)
→C++/CLIではインターフェイスの明示的な実装は別名を付ける必要がある(だから関数の代入構文(へんなの・・・))
→でもその別名は外に公開したくない(だからprivate)
→privateな仮想関数はこれ以上オーバーライドできないよ(だからsealed)
だと思う。一応言っておくとE::g()はI型の参照経由ならちゃんと呼び出せます。
個人的には明示的な実装に別名付けさせることの必要性が納得いかないんだけどね。
>通常クラスで流儀が違ってくるのはいただけない感じ。
むしろ違うものを似せて作ってあるから混乱することの方が多いような。
C 使いの漏れには ^ が何なのか読めん
796 :
デフォルトの名無しさん :2007/01/18(木) 16:52:18
何らかのファイルの入出力ライブラリ(具体的に使用するのはFBX SDK)があって、 それをC++/CLIでラップしてC#で使えるようにする場合、 プロジェクトの新規作成>VC++>CLR>クラスライブラリ でいいんですか? あと、プリコンパイル済みヘッダーは使用する設定でいいんですか?
798 :
デフォルトの名無しさん :2007/01/19(金) 11:51:55
アンマネージのクラスからマネージクラスをfriend指定したいのですが 「静的でないメンバ関数の呼び出しが正しくありません」とエラーが出てうまくいきません。 マネージクラスをアンマネージからfriend指定することはできないでしょうか? もしくは単純に書き方がおかしいんでしょうか。 ↓のような感じでイベントがあったらAppの関数を呼びたいです。 //アンマネージクラス class App { friend ref class Form1;//(friend class Form1 でもダメでした) public: App(); ~App(); void call(); }; //マネージクラス(フォームアプリでデザイナが吐いたクラス) public ref class Form1 : public System::Windows::Forms::Form { 〜略〜 }; System::Void Form1::trackBar_ValueChanged(System::Object^ sender, System::EventArgs^ e) { App::call(); }
>>798 書いてあるとおりで、Appのインスタンスの関数を呼ぶならばそのようにする必要があるし、
App::call()を静的メンバ関数にするならばstatic void call();と宣言する必要がある。
>>799 すいません、ありがとうございました。
staticにすることでビルドは通りました。
意味的にも段々わかってきました。
801 :
デフォルトの名無しさん :2007/01/22(月) 16:10:28
C++/CLIで構造体やクラスのサイズ取得するのってどうすればいいんですか? sizeof演算子使うとエラー出ます。
これだけのヒントから解けますでしょうか? C言語で4次のルンゲクッタを使用して、バネ振り子の位置変化についてやっています。 どなたか教えていただけないでしょうか? t=0.0; x=1.0; dt=0.1; x=x0; t=t0; v=v0; for(i=1; i<=100; i++) { x1=x(t) x2=x(t)+0.5*dt*v1 x3=x(t)+0.5*dt*v2 x4=x(t)+dt*v3 x(t+dt)=x(t)+dt*(v1+2*v2+2*v3+v4)/6 v1=v(t) v2=v(t)-0.5*dt*(k/m)*x1 v3=v(t)-0.5*dt*(k/m)*x2 v4=v(t)-dt*(k/m)*x3 v(t+dt)=v(t)-dt*(k/m)*(x1+2*x2+2*x3+x4)/6
これだけのヒントから解けますでしょうか? C言語で4次のルンゲクッタを使用して、バネ振り子の位置変化についてやっています。 どなたか教えていただけないでしょうか? t=0.0; x=1.0; dt=0.1; x=x0; t=t0; v=v0; for(i=1; i<=100; i++) { x1=x(t) x2=x(t)+0.5*dt*v1 x3=x(t)+0.5*dt*v2 x4=x(t)+dt*v3 x(t+dt)=x(t)+dt*(v1+2*v2+2*v3+v4)/6 v1=v(t) v2=v(t)-0.5*dt*(k/m)*x1 v3=v(t)-0.5*dt*(k/m)*x2 v4=v(t)-dt*(k/m)*x3 v(t+dt)=v(t)-dt*(k/m)*(x1+2*x2+2*x3+x4)/6
>>801 マネージド型でsizeofが使えるのは値型だけ
value class か value struct を使う
今VC++6.0のソースをVC.net 2005に移植しようとしています。 VC++6.0のソースは.cで書かれているC言語です。C++でもありません。 C言語で書かれたWindowsAppllicationです。 納品先からVC.net2005を指定されました。サポートがあるからだそうで。 なのでVC++6.0のdswをVC.net 2005で開いて、自動で変換されました。 sprintfとかが古い形式だといわれて、すべて直しました。 これで、うごけばそれでいいと上司に言われました。 無事に動きました。テスト仕様書もクリアーしました。 これで仕事は終わりです。 皆様、これのデメリットを教えてください。 コンパイルオプションはclrを設定せず”共通言語ランタイム サポートを使用しない”です。 ランタイムライブラリは"マルチスレッド DLL (/MD)"です。 コンパイル言語の選択は"C++ コードとしてコンパイル (/TP)"です。 実際問題、 そんなに実行速度が遅いともかんじません。 マネージコードとアンマネージコードを両方つかってるわけではないので 切り替え時間もありません。 プログラム上に.net frameworkを一切使ってません。 会社の財産をそのまま使えたということで このまま行くみたいなんです。個人的にはマネージドコードで作成しなおしたいのですが。 客からは金ももらえないし、時間もないそうです。 なんか、時代の流れに乗っていないのです。 なんか、私の気づかない問題点があれば教えて下さい。
最後の、 >なんか、時代の流れに乗っていないのです。 ここの行だけ読んだ。
>>808 807で、書いたものです。長すぎましたかね。失礼しました。
縦読みかジョークにしか思えん文章なんだが、 困ったことに縦読み箇所も笑いどころも見つからないんだ。
>>810 807で書いたものです。
ジョークではないです。なんか私が気のつかない観点からアドバイスを
もらえればと。それだけです。縦読みではないです。
>共通言語ランタイム サポートを使用しない まぁこの時点でスレ違いなんで他でもっと簡潔に聞いてみるがよろし。
> 個人的にはマネージドコードで作成しなおしたいのですが。 なのですれ違いではないのでは? まあ、個人じゃなくて仕事なんだから、動いているコードは弄るなでFAでしょ.
>>806 そもそも自動変数として宣言できるときにはそれを使えばすむ。
そういう風によそから得たハンドルに対してC++デストラクタ (IDispose.Dispose)を確実に呼び出したければ、
msclr::auto_handle(たぶんアンマネージ版msclr::gcroot)を使うしかないと思う。
逆に言えばその必要がなければ(当たり前だけど)単にハンドルを保持すれば十分。
と、お前が考えていそうなことと変わらないと思うぞ。
815 :
VC6 から VC8 (.Net2005) への移行 :2007/01/30(火) 10:55:28
>>807 for 文で宣言した制御変数のスコープが VC6 と .Net2005では違うので注意しろ……とレスしようと思ったが、
C++ ではなく C なのか。なら関係ないね。後、気をつけるべき点は wchar_t が unsigned short のtypedefではなくなったことぐらいか。
#include <stdio.h> int main(void){ char moji[26]; int i; for(i=0;i<25;i++){ moji[i] = i + 65; } nyuuryoku: printf("1〜26で頼む。\n"); scanf("%d",&i); if(i<27 && i>=0){ i -= 1; printf("%c",moji[i]); }else{ goto nyuuryoku; } return 0; } 数字入れたら、A〜Zの文字が出るように書いてみたんですが、 26を入れてもZがどうやっても出てきません。何ででしょうか・・・・・・?
最初から配列にセットしてないから。 恐れもなく goto を使う兵だな。 ループ構造がわかってるなら、break のことも勉強しる。
>>817 レスdです。
最初から配列にセットしてないとはどういう意味でしょう・・・・・?
「文字コードを代入して表示できるのかなー?」的な考えでやってみたのですが・・・・・・
goto文ってあまり使わないほうがいいんですね。
初めて知りました。。
>>814 なるほど。
.NET関連の資料を探していると、どうしてもC#のものが多いのでC++/CLIに読み替えないといけないわけですが、
例えば、using(SqlTransaction tran = con.BeginTransaction()) {...}みたいな構文になっているところは、やはり
ちゃんと後始末をした方がいいんでしょうかね。
ちょっと教えてくださいな 1.マネージドなアセンブリに、ネイティブなスタティックライブラリを リンクさせることはできるんでしょうか? (アセンブリの使用者に、ネイティブDLLの配置を気にさせたくない) 2.既存のライブラリの関数の引数がこうなってます↓ typedef void* HANDLE int Open(HANDLE& com); int Close(HANDLE com); そこで、こんなクラスから呼び出そうとしました。 ローカル変数なら大丈夫ですがインスタンスフィールドの場合はコンパイルすら通りません。 pin_ptrというものを使えばいいらしい、と考えましたが、さっぱり分かりません。 どうやればインスタンスフィールドを関数の引数に使えますか? ref class Cls { private: HANDLE _handle; public: Cls(void); void Test(){ HANDLE handle; Open(handle);//OK Open(_handle);//NG } };
>>821 >pin_ptrというものを使えばいいらしい、と考えましたが、さっぱり分かりません。
pin_ptr<HANDLE> ph = &_handle;
Open(*ph);
ま、話1割くらいにきいとけ
>>819 レスthx!!
ありがとうございました。
C++/CLIの衝撃。ISOになれなかったという事実。
823じゃないけど
>>824 やっぱり実際使おうと思うと、そんなに画期的な物じゃないんですよね?
DbProviderFactoryから作るDbConnectionとかDbCommandとか、TcpClientから作るNetworkStreamとか、
こういうのこそ生存期間を管理したいのに適用できないし、
自動変数より自動変数じゃない変数の方が多い所で使うと、ドット演算子と->演算子が変に混ざって可読性が下がるしで、
自分は結局、実業務では自己満足レベルしか使えてないです。
そればかりか、返ってusingがなくてauto_handle使わなきゃいけないから、C#より無駄なコードが多くなってたり。
>>823 >Written By: 川俣 晶
ここまで読めば残りは読まなくてもOK
まさにそのとおり
830 :
820 :2007/01/31(水) 12:48:07
>>827 が代弁してくれましたが、何となくそんな気がしたんですよね。
検索する中で
>>823 も読んでいたので、何かテクニックがあるのかと思っていたのですが。
831 :
デフォルトの名無しさん :2007/01/31(水) 15:33:33
auto_gcrootやauto_handleをメソッド内で宣言してつかう場合に次の両方の書き方が出来るのだけど -> か . かを使いたいかで使い分ければいいのでしょうか? auto_gcroot<M1^> m1(gcnew M1()); m1->func(); auto_handle<M1> m1(gcnew M1()); m1.func(); MSDNには auto_gcrootは「ネイティブ型に仮想ハンドルを埋め込むために使用できる自動リソース管理」 auto_handleは「マネージ型に仮想ハンドルを埋め込むために使用できる自動リソース管理」 と説明があるので気になっております。クラスのタイプによって使い分けなければいけないとかありますか?
ネイティブクラスは、マネージクラスのオブジェクトをメンバに持てない。 マネージ(値・参照)クラスは、ネイティブクラスのオブジェクトをメンバに持てない。 だから、クラスのメンバでは自ずとどちらを使うか決まってしまう(auto_gcrootはネイティブクラス、auto_handleはマネージクラス)。
>>832 返答ありがとう。
クラスのメンバーで使いかたを間違った場合はコンパイルエラーになるからわかるのだけれども、
main関数やクラスのメソッド内でローカルに使った場合に使い分けがあるかどうかがわからないのです。
どちらもコンパイル・実行時ともエラーにはならないようです。
特に使い分けは考えられていないと思う。 強いて言えばauto_handleが使えるところではauto_handleを使っておけばいいのでは、と俺は思う。 そういえばアンマネージド (#pragma unmanaged)な部分では関数でもauto_gcrootしか使えないだろうな。
835 :
デフォルトの名無しさん :2007/02/08(木) 23:12:52
JAVA の instanceof みたいに、オブジェクトがある型のインスタンスかどうかを確認するにはどうしたらいいのでしょうか?
RTTI
dynamic_cast とか C# の is 演算に該当するものってあったっけ?
839 :
835 :2007/02/09(金) 01:35:25
RTTI をぐぐって、とりあえずこれでイケました。 if( MyObj->GetType() == MyClass::typeid ) 〜 けど、MyObj が MyClass の派生クラスのインスタンスだと false になっちゃうのがイマイチです。 もうちょっと探してみます。
841 :
デフォルトの名無しさん :2007/02/09(金) 02:26:31
それはさておき、自分の目に留まった情報からの試行錯誤の結果、次のやり方で OK でした。
if( MyClass::typeid->IsAssignableFrom( MyObj->GetType() ) ) 〜
>>840 ありがと!それも参考にしてみます。
他のアドバイスをシカトしてるわけじゃないんですよ。
順を追っていろいろ試してみたかったもので。
842 :
デフォルトの名無しさん :2007/02/10(土) 19:15:02
カレントディレクトリ内から指定した拡張子のファイル名を取得したいのですが、 実際は複数あるはずのファイルが一つしか見当たらなかったりしてうまくいきません。 どこがおかしいでしょうか?配列の生存範囲とかは関係ない・・・ですよね? 変なところがあったら教えてください。お願いします。 private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e){ String^ currentDir = Directory::GetCurrentDirectory(); textBox1->Text = currentDir; array<String^> ^files = gcnew array<String^>(1); serchFilesInDir(currentDir,"*.txt",files); for each(String^ file in files){ textBox2->Text += file; } } private: void serchFilesInDir(String^ currentDir, String^ ex ,array<String^> ^files){ //現在のディレクトリ内のファイルを検索 array<String^> ^curDirFiles = Directory::GetFiles(currentDir, ex); for each(String^ file in curDirFiles){ files[(files->Length)-1] = file; Array::Resize(files,(files->Length)+1); } //現在のディレクトリ内にディレクトリがあれば再帰的に検索 array<String^> ^dirs = Directory::GetDirectories(currentDir); for each(String^ dir in dirs){ serchFilesInDir(dir, ex,files); } }
>>842 private: void serchFilesInDir(String^ currentDir, String^ ex ,array<String^>^% files){
つーか素直にList<>を使えよ(笑
844 :
デフォルトの名無しさん :2007/02/10(土) 19:56:45
>>843 うまくいきました。
しかもそんな便利なものがあるって知らなかったです。
ありがとうございました。
そして祥子は俺のアナルを
続きが気になる。
わっふるわっふる
847 :
デフォルトの名無しさん :2007/02/11(日) 02:18:28
すんません、array<String^>^% files の % ってどういう意味なんですか?
参照 ネイティブ C++ の引数に使う & と大体同じ
849 :
847 :2007/02/11(日) 02:54:18
>>848 ありがとうございます。
array<String^> は、String オブジェクトへのポインタの配列ですよね。
array<String^>^ は、そのポインタ配列オブジェクトへのポインタですよね?
array<String^>^% となると、ポインタ配列オブジェクトへのポインタの参照ということになりますか?
>>843 のように定義される関数の場合、関数内で files へ値(新たな array<String^>^) を代入すると、呼び出し元の
変数の内容もその値に変化するということになるでしょうか?
試してみればいいじゃない あと ^ はポインタじゃなくてトラッキングハンドル。 別名ハンドルとか参照とか。参照は % と区別付けづらいけど。
851 :
デフォルトの名無しさん :2007/02/11(日) 13:37:22
std::map<gcroot<String^>,int> hoge; ってダメなんですか? vectorはgcrootでマネージ型持てるみたいなんですが。
852 :
デフォルトの名無しさん :2007/02/11(日) 13:47:30
もしくはstlのmapに変わるものはcliでないでしょうか? でもネイティブクラスのオブジェクトへのポインタを持ちたいんで その条件を満たしてくれないといけないのですが。
とりあえずこれだけのコードはコンパイルできたぞ。 // Visual C++ 8 // cl /Zs /clr test.cpp #using <mscorlib.dll> #include <map> #include <msclr/gcroot.h> int main() { std::map<msclr::gcroot<System::String^>, int> hoge; }
CLI つーか .NET 的には SortedList<TKey, TValue> / SortedDictionary<TKey, TValue> かね
レスありがとうございます。
>>853 うちもmap作るだけならできましたけど
insertの段階でエラーでませんか?
今試していたら一瞬コンパイル通ったきがしたけど(気のせいか)やっぱダメみたいです。
>>854 試してみてダメだったんで、一応なんか自分のうっかりじゃないか確認で聞きたいんですが、
ネイティブオブジェクトのインスタンスとかポインタは入れられないですよね?
856 :
デフォルトの名無しさん :2007/02/12(月) 02:46:59
マネージドなクラスの関数中に、文字列と数値の対のような、ちょっとしたテーブルを作りたいと思いました。 ref class testclass { void func() { static const struct { const char *p; const int x; } tbl[] = { { "abc", 100 }, { "def", 200 }, { "ghi", 300 } }; } }; ところがこれは、「ローカルクラス、構造体、または共用体の定義は、マネージクラスのメンバ関数では使用できません」となってしまいます。 このようなテーブルはどう実現するべきなのでしょうか?
>>856 ref class testclass {
ref class ABC {
String^ s; int x;
public:
ABC(String^ s, int x) { this->s = s; this->x = x; }
property String^ S { String^ get() { return s; }};
property int X { int get() { return x; }};
};
static initonly array<ABC^>^ tbl = { gcnew ABC("abc", 100), gcnew ABC("def", 200), gcnew ABC("ghi", 300) };
public:
void func() { ... = tbl[0]->X; }
};
ref classの実装も.cppに書かなきゃいけなくなるがお気楽な方法もある。 // .h ref class testclass { void func(); }; // .cpp static const struct { const char *p; const int x; } tbl[] = { { "abc", 100 },{ "def", 200 },{ "ghi", 300 }}; void testclass::func() { ... = tbl[0].x; }
859 :
856 :2007/02/12(月) 06:57:47
>>857-858 うーむ、なるほど。
できるだけ狭いスコープ内で、できるだけ軽く定義したいのに、なかなか不便なものですね・・・
しかも struct はこのように回避できそうですが、union とかは難しそうですね。
struct や union の中身がネイティブなものだけだったら仕様的に問題なさそうなのに、惜しいです。
なんにせよ、ありがとうございました。
>>855 854ではおそらくマネージオブジェクトしか入れられない。
std::mapでエラーになる原因は、std::mapがキーに対して通常operator <を要求するため。
しかしmsclr::gcroot<System::String^>はそれを持っていないのでエラーになる。
だから独自の比較子を定義してやればよい。
struct SystemStringComparer : std::binary_function<
const msclr::gcroot<System::String^>&,
const msclr::gcroot<System::String^>&, bool>
{
result_type operator ()(first_argument_type x, second_argument_type y) const
{
return System::String::Compare(x, y) < 0; //CompareOrdinalにすると文字コード順で比較される
}
};
int main()
{
using msclr::gcroot;
using System::String;
typedef std::map<gcroot<String^>, int, SystemStringComparer> HogeMap;
HogeMap hoge;
hoge.insert(HogeMap::value_type(L"Hoge", 5));
std::cout << hoge[L"Hoge"] << std::endl;
}
>>860 大変良く分かりました。
今回は仕方なく全部ref classに大改造して
Dictionaryに持たせるようにしてしまった後だったので
次の機会のために忘れないように保存しときます。
ありがとうございました。
>861 次の機会があるなら STL/CLR でも調べておいたら?
863 :
デフォルトの名無しさん :2007/02/17(土) 04:28:36
CLI?CLR? 空のCLRプロジェクト作ってでhelloworld出力してみたんですけど コンパイル、リンク、実行までえらく時間がかかるんですが これは、コンパイル、リンクでexeを作るまでに時間がかかってるだけなんでしょうか 実行してみて「えれ〜時間かかるな」と思い質問さしていただきます。
>>863 おそらくメモリー不足、128Mぐらいで使ってるとかしてない?
865 :
デフォルトの名無しさん :2007/02/19(月) 23:26:27
トラッキングハンドルを、ハンドルの値として比較したいです。 これをするのに obj1 == obj2 とした場合、== 演算子がオーバーロードされてると意図したことができなそうです。 どうすべきでしょうか?
System::Object::ReferenceEquals
867 :
865 :2007/02/20(火) 00:33:43
>>866 それだ!すばらしい!
ありがとうございました!
868 :
デフォルトの名無しさん :2007/02/23(金) 17:02:23
オブジェクトが既に delete されているのかどうか確認する方法はありますか?
必要なら自分で用意するもんでしょ
870 :
868 :2007/02/23(金) 17:32:06
>>869 それは、オブジェクトの外のどこか別のところにフラグのようなものを持つということでしょうか?
ハンドルだけで簡単に判断する方法が無いのでしたらそうしようと考えているのですが。
delete されたオブジェクトは存在しません。
872 :
868 :2007/02/23(金) 17:44:46
>>871 オブジェクト自体は存在しないのは重々承知です。
でも、そのオブジェクトをかつて指し示していたハンドルというか、ハンドルの値が変数に残っているわけで。
確認する方法が無いなら無いなりに設計しますし、マネージドならではの機能があるならそれを利用しようと考えてるのです。
873 :
デフォルトの名無しさん :2007/02/23(金) 17:45:59
staticなカウンター作れ newで++ deleteで-- とか
>>872 WeakReferenceで参照しておけば、開放された場合に target が null になるけど
そういうようなことだろうか。
875 :
868 :2007/02/23(金) 18:04:36
>>873 それだと、一つのクラスは一つのインスタンスしか管理できないような・・・
というか、二重 delete 防止の方法については自分で考えますので大丈夫です。
>>874 ちょっと WeakReference について勉強しにいってきます。
ありがとうございます。
一応やりたかったことを補足しておきますと、あるクラスがメンバとして
MyClass^ m_obj;
を持っていたとして、コンストラクタで m_obj = gcnew MyClass(); のようなことをして、
デストラクタで delete m_obj; するのです。
しかしデストラクタが呼び出される前に、どこかで delete m_obj; されるケースがある場合、
つまりデストラクタにやってきた段階では既に m_obj は delete されていた場合、
この m_obj の値だけでそのことを判別することはできるのか、
ということです。
いや、どっかで誰かが delete するなら、その時に m_obj を nullptr にしておくなどと言う
方法があるとは思いますが、勉学のために質問してみました。
Dispose でいいじゃん
>>875 漏れの個人的な意見だけど、
誰が何時開放してもいいようなオブジェクト
⇒ gc に任せる
ファイルを排他オープンしてたりして、寿命管理をちゃんとやりたいオブジェクト
⇒ 何時解放するか、解放済みか、などちゃんと管理する
って感じなのであんまりそういうことをしたくなったことは無いなぁ。
878 :
868 :2007/02/23(金) 18:18:56
なんとなくですが、WeakReference は違うっぽいかも・・・
>>877 確かにそうなんですけどね。
もしマネージドの機能としてそんなのがあるなら、簡略化したコードの書き方も考えられるかな、とか思いまして。
だから、無いなら無いでいいんです。
879 :
デフォルトの名無しさん :2007/02/24(土) 00:11:11
Acrobat でウェブサイトをクロールして PDF にする機能あるでしょ
881 :
デフォルトの名無しさん :2007/02/24(土) 00:29:39
>>880 Acrobat の機能はどうでもよくて、pdf版のC++/CLIの仕様書の日本語訳が欲しいんだけど。
ないだろそんなもん。
883 :
デフォルトの名無しさん :2007/02/24(土) 01:00:56
使えねーな。
自分でpdf化すればいいんじゃね?
885 :
デフォルトの名無しさん :2007/02/24(土) 01:15:27
どうやって?
887 :
デフォルトの名無しさん :2007/02/24(土) 01:21:04
Acrobat なんて持ってないのだが。
買えよ。安いんだから。
889 :
デフォルトの名無しさん :2007/02/24(土) 01:53:36
安くねーよ。持ってる奴がPDF化しろや。
貧乏人乙w
891 :
デフォルトの名無しさん :2007/02/24(土) 01:59:23
お前、Acrobat がいくらか知ってるのか?
8Stdが3万とちょっとだろ
893 :
デフォルトの名無しさん :2007/02/24(土) 02:11:31
安くないだろ。
だから貧乏人なんだよ^^
895 :
デフォルトの名無しさん :2007/02/24(土) 02:42:44
Acrobat 買って貧乏になったのか?3万くらいで貧乏になるなよ。
>>875 ところで、refクラスのdeleteって出来たっけか?
>>896 は勘違い忘れてくれ。mc++とごちゃ混ぜだった。
deleteしてもDispose()が呼ばれるだけだから、オブジェクトそのものはGCされるまで残っている。
だからプロパティを参照しても問題なし。
ref class xxx {
bool disposed;
public:
property bool Disposed { bool get() { return disposed; } }
xxx() { disposed = false; }
~xxx() { disposed = true; }
};
gcnewしたインスタンスを自分で消したいときって nullptr代入すればよい? 一応それで狙った動きはしてるみたいですが。
897が書いているようにdeleteしてDispose(C++デストラクタ)を呼んで、 それから(変数のスコープがまだ終わらないなら)nullptrを代入するほうがいいかもしれない。
とは言え nullptr 代入したからってすぐ消えるわけじゃなし わざわざ nullptr 使うのはよほど寿命の長いインスタンスのメンバが途中でいらなくなるときくらい でそんな状況って凄く稀だよね
901 :
デフォルトの名無しさん :2007/02/24(土) 15:24:21
nullptr 代入は、オブジェクトの破棄タイミングは GCまかせになるんでしょ? で、破棄されるときにはオブジェクトのファイナライザが呼ばれると。 delete は、オブジェクトはすぐ破棄されるんでしょ(メモリの回収がいつ行われるかはGCまかせだろうけど)。 この破棄時にはデストラクタが呼ばれると。 ちがったっけ?
902 :
デフォルトの名無しさん :2007/02/24(土) 23:57:42
C++/CLIって、STL使わなくてもC#以上に使いやすい?
素直にC#にしとけ
904 :
デフォルトの名無しさん :2007/02/25(日) 00:19:14
C#に比べてC++/CLIはどの辺が使いにくいの?
>>904 「stl使わない」とか書いてるからC++適性がないと思われたんだよ
おとなしくC#でP/Invokeしとけ。
906 :
デフォルトの名無しさん :2007/02/25(日) 00:30:41
やっぱりC++/CLIはSTL使わないと使いにくい言語なんだ。
STLを使わないような人には使いにくい言語ってこと。
908 :
デフォルトの名無しさん :2007/02/25(日) 00:33:32
要するにC++/CLIはSTL使わないと使いにくい言語ってことでしょ。
C++/CLI でSTLを使わないような人 Lisp で再帰を使わない人 Perl で正規表現を使わない人 には使いにくい言語です。
そもそも元のC++がSTL使わないと使いにくい言語なんだから、 C++/CLIでもそうだと思っても構わないと思う。 でもSTL以外にもC++の特長は色々あるし、そこを見出して .NETでC++/CLIを使うという選択肢を選ぶ人がいたって構わないだろ。
911 :
デフォルトの名無しさん :2007/02/25(日) 00:46:26
912 :
デフォルトの名無しさん :2007/02/25(日) 00:50:41
STLがないとC++/CLIは、再起のないLispや正規表現のないPerl並に使いにくいってことか。
C++/CLIを単にC++に置き換えれば成り立つと言っていいと思う。 C++/CLIではSTL抜きでも、単にネイティブなCやC++のライブラリに対する マネージドなラッパを作るなんて用途だったら別に困らないと思う。
待てよSTL/CLRなんてのも作っているようだし、 やっぱりC++/CLIにもSTL(というよりテンプレート)は 欠かせないということでいいと思う。
そもそもC/C++って組み込み寄りの言語だと思うんだけど。 C++はあいまいだけど。
まさか
917 :
デフォルトの名無しさん :2007/02/27(火) 09:43:23
標準で難読化ツールついてないの?
難読化したいところだけアンマネージでどーぞ。
919 :
デフォルトの名無しさん :2007/03/04(日) 10:53:24
C++/CLIで.NETライブラリ使い倒せば、STLとかBoostとか全く使わなくてもいいんだよね? かつ、そっちの方が便利なんだよね?
便利かどうかはしらんが、完全に置き換えることはできる。
C++/CLIでSTL使うなんてキモすぎる。
それなら素直にC#使ったほうがいいんじゃないの?
要は、C++/CLIってSTL使えることくらいしか、C#に勝る点は無いってことだな。 STLも.NETつかえばC#には全く不要だけどな。
C#に移行しても問題ない環境ならそりゃそうだろ
MS発表でも、C++/CLIはアンマネージなレガシーコードと糊付けに 使うために使ってね、って言語だから。
C#はマネージドポインタ(トラッキング参照)が関数の引数でしか使えない。
まあそれで困ることがあるかというと無いんだけどな それより既存の C++ の資産を C# ほどには労せず使えるという点が最大の利点だろう?
つまり言語仕様ではC++/CLIは、C#に勝てないってことか。
C#がやりすぎなところを省略できるC++ C++がやりすぎなところを省略できるC# ケースパイケース
まあ、C#の方が後出しなんだから、すべての面で優れていて当然。
世の中にはトレードオフというコトバがあってな
C#がすべて優れてると思えるのって幸せだね・・・
過去の資産以外C++にはメリットないでしょ。
C#がすべて優れてると思えるのって幸せだね・・・
すべてではないな。ほとんどすべて、という言い方が正しい。
C#が優れてると思えるのって幸せだね・・・
C#が優れてないって思えるのは相当不幸だよ。
ケースバイケース。仕事環境によるだろ。
C++/CLI縛りの職場ってどう考えても不幸だろw
C++/CLIなのにフォーム以外のクラス継承が 一切禁止されてるプロジェクトってどうよ。
それより VisualStudio 2005 の重さに閉口する
>>942 あなたのPCにメモリが足りてないか、あなたにカルシウムが足りていない。
Eclipseの方が重くね?
notepad.exeより軽くなったら使ってやってもいい。
つまりnotepadをくそ重くすればいいんだな。
腕の良い呪術師を探せばあっという間だな。
C++/CLIはC++より速いの?
書き手による
どういう書き手ならC++/CLIがC++より速いの? どういう書き手ならC++がC++/CLIより速いの?
無能であるかそうでないか
100% C++の文法で書いたソースを /clrでコンパイルしたものを C++/CLIと呼ぶかどうかという問題はある。
いまいちわかんないんだけどさ、C++/CLIって中間コードへコンパイルするんじゃないよね? インテルやAMDのネイティブなアセンブラになるんだよね?
オプションによる
>954 どういうオプションでなる? 詳しい説明がある所のポインタを教えてもらえるとありがたい。
>>955 /clr あとはMSDNかGoogleで
C++/CLI そのものはただの言語なのでどうコンパイルするかはコンパイラ次第なのだが と使い古された半畳
C++/CLI のコンパイラっていくつあるの?
Visual C++ 2005とたぶんVisual Studio Orcas CTP
doubleがNaNかどうかを判定する方法を教えてください
Double::IsNaN メソッド
962 :
デフォルトの名無しさん :2007/03/29(木) 22:15:49
すいません、これコンパイル通らないんですが仕様ですか? public ref class Test1 { array<String^>^ strs; public: Test1(array<String^>^ strs) : strs(strs){;} }; public ref class Test2 : public Test1 { public: Test2(void) : Test1(gcnew array<String^>{"test1", "test2"}){;} //←ここで引っかかる模様 };
>>962 確かに通らないね。文法上の制約なのか、コンパイラの制約なのかはわかんね。
964 :
962 :2007/04/04(水) 17:18:38
ありがとう。 で、今日はこれコンパイル通らんかった。 初期化子の数が多すぎるそうです。 何でも一度に書くなということでしょうかね。 public ref class Test1 { public: Test1(void){;} Test1(array<Test1^>^ tests){;} }; /////////////////////////////////// array<Test1^>^ test1 = gcnew array<Test1^>{ gcnew Test1(), gcnew Test1(), gcnew Test1(gcnew array<Test1^>{ gcnew Test1(), gcnew Test1() }) };
#include <stdio.h> void change(int *a,int *b); int main(void){ int a=5,b=3; change(&a,&b); printf("%d,%d",a,b); return 0; } void change(int *a,int *b){ int c; c=a; a=b; b=c; } aとbを入れ替えるchangeを作りたかったんですがこれだとうまくいきません どこを直せばいいですかね?
#include <stdio.h> #include <algorithm> void change(int *a,int *b); int main(void) { int a=5, b=3; change(&a, &b); printf("%d, %d", a, b); return 0; } void change(int *a,int *b) { std::swap(*a, *b); } まあ細かいことは気にしない。
まあ、なんだ。ポインタを入れ替えてどうする、と。 ていうかcに代入する時点でエラーか警告出てない?
ん〜・・・ よくわからねーんですが int *a この *aはINT型でなくINTのポインタ型 aがINT型 &aがアドレス型? なんですかね・・・ c=aとしちゃうと、INT型とINTのポインタ型は違う型だから代入できないってことなんでしょうか^^;
void change(int *a, int *b) { int c; c = *a; *a = *b; *b = c; } 次からはただのCのスレ行けよ。
実践C++/CLI(中 博俊)を読んでC++/CLIを読んでるけども、 文法はある程度分かっても、クラスライブラリがどうなってるかが全く分からない。 例えば、文字列を表示するにはどれを使えばいいかとか.... MSDNライブラリは大量の項目で羅列してるけど、「〜をしたい場合には〜を使う」みたいな使い方はサポートしていない希ガス。 どうやって勉強すれば良いんだろうか.......
ライブラリはとにかく使ってみて、どれがどういう場合に最適か覚えるしかないだろ 経験がないことには話にならん
その際にはC#やVB.NETのコードを読めると吉。
質問です。
ttp://www.atmarkit.co.jp/fdotnet/special/vcppinvista01/vcppinvista01_02.html の通りに、関数をラッパするクラスを作って、ネイティブ関数をmanagedな言語
から呼び出すとき、
*.lib (ネイティブ関数ライブラリ)
から
*.dll (managedライブラリ)
を生成する際に
hello.lib(hello.obj) : warning LNK4075: /EDITANDCONTINUE は /INCREMENTAL:NO の指定によって無視されます。
という警告が出ます。
一応、警告を気にせずに実行すれば動作はするのですが、
イマイチ気分的にすっきりしません。
なぜ警告が出るのかわかる方いますか?
ちなみに環境はWinXP + Visual Studio 2005です。
977 :
976 :2007/04/09(月) 15:41:22
追記: 関数のラップクラス(hellolib)では、リンカのインクリメンタルオプションは /INCREMENTAL で有効になっています。 また、ネイティブ関数のライブラリ(hello)では、そもそもプロジェクトの プロパティページにリンカの設定をする項目がありませんでした。 警告で出ている/EDITANDCONTINUEは、プロジェクトのプロパティ からどこか探したのですが、どこにあるか発見できませんでした。
978 :
デフォルトの名無しさん :2007/04/12(木) 13:04:00
C++CLIの存在意義はなんなんだろう? 釣りじゃなくってホントそうおもう C#じゃだめなの?
979 :
デフォルトの名無しさん :2007/04/12(木) 14:20:49
>>978 Java厨を引き込むためのJ#
ブヴィ厨を引き込むのためのVB.NET
ぷらぷら厨を引き込むのためのMC++, C++/CLI
>>978 ネイティブとマネージドの世界の橋渡しにはいいと思う。
C#でのinteropと違って、C/C++に用意されたヘッダファイルがそのまま使える。
982 :
デフォルトの名無しさん :2007/04/17(火) 05:34:22
そろそろ結論を言おうか? ネイティブ吐けるC#こそ最強! あったらの話だけどね。 C++/CLIはちと難しすぎるというかややこしいんだよね。 というのもC++から入ってから.NETに行くことになるから。 やっぱ.NETから入ってネイティブという流れで学べる環境じゃないと広がらないと思うんだ。 だからこそネイティブ対応のC#を切望しているわけ。 いまのところC++やっている人はC++/CLIやってくれたらいい。 VB/JAVAやっている人はぜひC#はじめてみてほしい。 初心者はもちC#! ネイティブC#かぁ〜、ホント楽しみだね。
朝から妄想オナニー?それとも込みか?縦ではなさそうだし最近のは難しいな。
984 :
デフォルトの名無しさん :2007/04/17(火) 08:54:03
いいかい、同じ.NET対応言語でもC#やVBは初心者にも門戸を開いている。 というよりかはC++が上級プログラマのための言語であるからして、 必然的に、それ以外のプログラマのための言語がC#でありVBだといえなくもない。 とにかくだ。 問題はC++/CLIがC#やVBどころか、C++よりも敷居の高い言語だということなんだ。 このギャップはいったいなんなんだとういう話さ。 わかったかい?
985 :
デフォルトの名無しさん :2007/04/17(火) 08:55:14
C++よりも敷居が高いなんて.NET対応言語としてあるまじきことではないか!?
既存のC/C++ヘッダーとlibファイルを引っ張ってきてマネージモジュールを 書けるC#があったら、それがC++/CLIってだけの話かと。
>>982 >>984 言いたいことはわからなくもないが、
残念ながらそれを書くべき場所としてここは相応しくない。
せめて.NET FrameworkのスレとかC#のスレとかでだったら共感できるのに。
お願いします。 動的に追加したContextMenuStripのメニューアイテムのすべてを 同じイベントハンドらに設定した場合、そのイベントハンドら内で どのメニューアイテムが選択されたのかを知る一般的な方法って あるのでしょうか? いろいろやって見ましたが、なんかうまくいきません。
最初に渡ってくるオブジェクトを調べれば?
990 :
988 :2007/04/21(土) 21:43:03
>989 最初にわたってくるオブジェクトとはイベントハンドらの第一引数の ことでしょうか? それはthis(メインのフォーム)になっているので、これを 変えればいいのでしょうか? しかしEventHandlerを作ったときの第一引数にToolStripItem^を 渡すとコンパイルエラーerror C3754になってしまいます。
991 :
988 :
2007/04/21(土) 21:50:14 すいません。ぼけてました。 いま調べてみたら第一引数は、ToolStripMenuItem^になってました。