くだすれC++/CLI(初心者用)part2

■ このスレッドは過去ログ倉庫に格納されています
2010/03/15(月) 09:41:19
おそらく、.NET開発でデファクトスタンダードに最も近いであろう
C++/CLIについて語ろうぜ!

このスレはC++および.NET Frameworkについて一定以上の知識を持っている人が対象となります。
.NETのクラスライブラリの使い方といった質問は Visual Studioスレにお願いします。

前スレッドはこちら
くだすれC++/CLI(初心者用)
http://pc8.2ch.net/test/read.cgi/tech/1142144110/l1

dat落ち姉妹スレ
C++/CLI part3
http://pc12.2ch.net/test/read.cgi/tech/1206447234/l1
http://pc11.2ch.net/test/read.cgi/tech/1142147319/l1
http://pc8.2ch.net/test/read.cgi/tech/1126450441/l1

managed C++ やろうぜ!! 002
http://pc8.2ch.net/test/read.cgi/tech/1139043535/l1
2012/03/15(木) 20:40:01.46
http://homepage3.nifty.com/ishidate/vcpp10_20/vcpp10_20.htm
ここの一番下の図5は図6用の計算式はどの様に記入すれば良いのですか。
2012/03/16(金) 10:49:25.88
function1のとこだろ
どう考えてもC++/CLIでやるべきことじゃないよなこれ
内容は凄いのに…C#にすれば…
2012/03/18(日) 11:04:51.87
おお、派手だなw
.net framework 使いたいだけならC#でいいなーほんとに
2012/03/18(日) 12:14:54.13
eのこと聞いてんのかな?
Math::Exp() にすりゃいいと思うが、、、、
2012/03/20(火) 20:55:02.08
こういう変に優秀な勘違いがいるからC++/CLIに手を出す奴がいなくならないんだよな
C++/CLIの記事や書籍ってC#やVBに比べて妙に良質だったりするし
2012/03/21(水) 00:15:02.30
C/C++では配列の終端の一つ次を指すポインタは有効なポインタだったのですけど、
マネージ配列の終端の一つ次を指す interior_ptr は配列がGCで移動したときに正常に更新されますか?
483482
垢版 |
2012/03/25(日) 13:00:47.00
いまさらですが、試してみたところ正常に移動するようでした。
484482
垢版 |
2012/03/26(月) 18:19:27.80
(勝手な推測ですが) interior_ptr はハンドルとオフセットのペアで実装されているのではないかと思います。

array<int> ^a;
auto pa = &a[3]; // { a, 12 }

int *p;
interior_ptr<int> ip (p); // { nullptr, p }

ところで、長さ 0 の配列 (b) に対して &b[0] は IndexOutOfRangeException なんですね…。困った困った。
2012/03/26(月) 21:59:14.05
配列でinterior_ptrなんて必要?
君が言ってるように常に配列のハンドルとオフセットをペアにしとけばよくね
interior_ptrってクラスのインスタンスフィールド指すのに使うやつでしょ
2012/03/27(火) 07:37:57.33
既存コードの一部だけマネージに持っていく実験なので。
*& はできても interior_ptr<T>% はできないので、配列 + オフセットの方が便利なのはその通りです。
487デフォルトの名無しさん
垢版 |
2012/05/27(日) 20:25:49.04
引数としてstring型の配列を用いたいのですが・・・
自分C#しかやったことないので・・・
2012/05/27(日) 20:28:19.00
void foo(cli::array<System::String^> ^bar);
489デフォルトの名無しさん
垢版 |
2012/05/27(日) 20:33:46.88
Thank you sir.
490デフォルトの名無しさん
垢版 |
2012/05/31(木) 15:51:08.78
cli::array<System::String^> ^hoge を char* hogehoge[] に変換したいのですが・・・
2012/05/31(木) 16:43:56.11
>>490
http://ideone.com/XGbqa
492491
垢版 |
2012/05/31(木) 17:00:23.87
すまん、コンストラクタが例外安全でなかったので修正した
http://ideone.com/xbcbh
493デフォルトの名無しさん
垢版 |
2012/05/31(木) 17:15:25.25
全然わかんね
2012/05/31(木) 17:26:57.22
cli::array<System::String^> ^hoge = ...;
char_pp p(hoge);
char** hogehoge = p.get();

ってことなんだが

char** は char* xxx[] を引数に取る関数にそのまま渡していい
495デフォルトの名無しさん
垢版 |
2012/05/31(木) 18:36:01.89
Hmm...
2012/05/31(木) 18:57:30.99
補足しておくと
・PtrToStringCharsで内部ポインタを取得
・System::Stringはunicodeなのでwcstombs_sでマルチバイト文字列に変換
・std::auto_ptr, std::vector, char_ppはRAIIイディオムにより例外安全にするため
・try{}catch(...){throw;}もchar_ppコンストラクタを例外安全にするため
用語はググってくれ

もしC++初心者で.NETからよそのライブラリ使いたいとかなら
C#からP/Invokeした方が多分楽
2012/05/31(木) 19:02:53.62
P/Invokeですか・・・
2012/06/01(金) 00:26:18.04
そんなコード書かれたら、俺なら普通に書き直しさせるわ
文字列のマーシャリングで標準のマーシャリング以外を使うなよ

marshal_context c;
for (...) native_str[i] = c.marshal_as<char*>(managed_str[i]);
2012/06/01(金) 03:21:17.29
それコンパイル通るの?
2012/06/01(金) 15:18:44.76
MFC 使うんだったら、CString に直接放り込めばいいだろうに
CString strBuff(strManaged);
501sage
垢版 |
2012/06/08(金) 17:29:51.46
VC++2008のC++/CLIでUSBカメラが抜かれたことを検知したいのですが,どなたかわかりませんか?
USBメモリーなら
virtual void WndProc(System::Windows::Forms::Message% m) override
{
if(m.Msg == WM_DEVICECHANGE)
{
switch((int)(m.WParam))
{
case DBT_DEVICEREMOVECOMPLETE:
MessageBox::Show("out");
break;
case DBT_DEVICEARRIVAL:
MessageBox::Show("in");
break;
}


}

Form::WndProc(m);

}
で判断できたんですが,USBカメラだとm.Wparamが変化しません...
502デフォルトの名無しさん
垢版 |
2012/06/09(土) 12:49:43.11
c++を使い始めたものなんですけど

こっちはちゃんとなるんですけど
http://www.dotup.org/uploda/www.dotup.org3073322.jpg

includeを使うと
http://www.dotup.org/uploda/www.dotup.org3073352.jpg


こんな感じになっちゃって・・・(´;ω;`)


だれか解決して下さいませんか?
2012/06/09(土) 12:58:27.44
苦Cか
504デフォルトの名無しさん
垢版 |
2012/06/09(土) 13:00:34.24
>>503
正解
あれはとてもためになります
ところで
対処の方法は?
505デフォルトの名無しさん
垢版 |
2012/06/09(土) 13:20:04.01
まずスレタイを読みます
506デフォルトの名無しさん
垢版 |
2012/06/09(土) 13:21:59.00
>>505
読みました
さようなら
2012/06/09(土) 13:40:18.44
わろた
508デフォルトの名無しさん
垢版 |
2012/06/19(火) 22:37:50.62
DOSで趣味でプログラム組んでた程度で、APIめんどくせ、MFCうぜえってレベルなんだが
久しぶりにちょっとしたゲームでも作ろうとして
VCに無料版があるのか!と飛びつき
無料版でフォームの統合環境まであるんか、今はMFCにかわってCLRなんかと早とちりし
ネット漁ればサンプルやら何やらゴロゴロしてるかと思えば…
何じゃこりゃ
2012/06/19(火) 23:16:03.51
CLRってなんだよ。CLIはMicrosoftにも見捨てられかけてるのでね…泣けてくる。
どうせ.NET使うならもうC#で全部やっちまえよって感じか?
2012/06/20(水) 01:01:15.51
CLIは規格の名前、それのMSによる実装がCLR
CLRに大量のライブラリ群を加えたやつが.NET Framework

CLIに対応する構文を追加したC++だからC++/CLI

>どうせ.NET使うならもうC#で全部やっちまえよって感じか?
その通り。過去の資産を使わないといけないというような、必要に迫られて仕方なく使う物だよ。
2012/06/20(水) 01:14:40.12
ところでVC++のC++/CLIってMS CLRじゃなくて純粋なCLIで動くの?
一応CLIではアセンブリはネイティブイメージを持てるという決まりだった覚えがあるけど
細かい相互運用のことは決まってなさそう
2012/06/20(水) 03:37:32.95
C++/CLIをMonoで動かそうとするとCRT使えない&/clr:pureだったよね。今は変わったのかな?
2012/06/20(水) 07:32:37.59
>>508
そういう用途だったら、C#おすすめだけどね。
プロトタイピングに最適!
2012/06/20(水) 11:20:48.23
/clr:safe だね。

using namespace System;
int main(array<String^>^ args) {
  Console::WriteLine("Hello World !");
}

cl /clr:safe test.cpp
mono test.exe
でいける。
2012/06/24(日) 02:05:59.36
http://www.atoker.com/blog/2012/04/12/llvm-europe-2012-cli-compiler/
ClangベースにC++/CLIコンパイラ作ったという話。
(1)と(2)とあるけど、どちらもVisual C++の吐く
混在アセンブリとは違う仕組みっぽい感じがする。
2012/06/24(日) 20:35:21.91
VC++のclrで,ref classはなぜref classからしか継承できないんでしょうか?
仕組み的に継承先でgcとか実装されるなら別にvalue classからとかでも継承できていいと思うんですけど……
2012/06/24(日) 22:14:12.48
というか普通のクラスをpublic refで継承したいのおおおお
2012/06/25(月) 11:36:44.70
継承出来ても仕組み上ハンドル変数にしか入れられないから意味なくね
2012/06/25(月) 15:36:06.92
構造体がなんかインターフェイスを実装してる場合には意味ないこともないが
CLIを拡張するのに見合った利益があるかどうか考えると当然切り捨てだろうな
あくまでC#とVBが主役なんだからC#やVBから使えないクラス作っても意味ない
2012/06/25(月) 18:42:31.48
混合型ェ・・・
2012/06/25(月) 22:06:41.59
混合型こそ仕組み的には特にできない理由がなくて比較的大きな利益のあるものだよな
CLIやCLRを弄る必要もなく、コンパイラだけで対応できるはず
永遠に将来的に対応予定だが
2012/06/26(火) 10:12:49.68
いや仕組み的に無理だから

マネージド領域のポインタはfixedなしに取得してはいけない
実装部分でそれを止める(無いことを保証する)には宣言部分で付加情報が必要
それがrefキーワード

ヒープ領域ならポインタを取得するのは問題ない
だからrefクラスのメンバにポインタ型なら定義可能
コンストラクタでnewしてCLIデストラクタ(IDisposable)でdeleteすること
2012/06/26(火) 10:13:55.17

template <typename T> ref class ref_auto_ptr{
   T* p;
public:
   ref_auto_ptr(T* ap):p(ap){}
   ~ref_auto_ptr(){delete p;}
   T* get(){return p;}
};

struct val_class{
   val_class(){Console::WriteLine(L"new val_class");}
   ~val_class(){Console::WriteLine(L"del val_class");}
};

ref class ref_class{
public:
   ref_class():p(new val_class()){}
   ref_auto_ptr<val_class> p;
};

int main(array<System::String ^> ^args){
   ref_class c;
   Console::WriteLine(L"a");
   return 0;
}
-----------------
new val_class
a
del val_class
2012/06/26(火) 12:26:48.81
仕組み的に無理って
C++/CLI のもともとの目的は混合型を実現することだったんじゃなかったか?
2012/06/26(火) 16:07:00.24
Some Notes about Mixed Types
http://blogs.msdn.com/b/branbray/archive/2005/07/20/441099.aspx
2012/06/26(火) 22:12:26.16
PODなネイティブ構造体をマネージ型に置いたり、マネージハンドルをメンバに持たない
マネージ構造体をネイティブ型に置いたりするのは別に問題ないが(ミスを誘発しやすいという懸念はあるが)
もっと一般的に混合型を扱えるようにする構想があったからとりあえず全部禁止しといたってことか
で結局はC++/CLIそのものが見捨てられて計画倒れになり、理不尽な制限として残ってしまったと
2012/06/27(水) 03:22:10.94
ちょっとした配列をメンバに持ちたいときにmallocしたりgcnewしたりしないといけないのは
なんとかならんかったんかなぁ、と思う。
2012/06/27(水) 08:24:51.05
>>525
Point* G(R^ r) {
pin_ptr<Point> pinp = &r.p;
return pinp;
}
これってGCの問題というよりはC++でもよくあるミスの一種だよね
ローカル変数のポインタを残すなってのと同類
2012/06/27(水) 10:51:13.99
初心者みたいな質問ですがすみません。

今、マネージコードからネイティブなコードを呼び出す ということがやりたいのですが
例えば、native_program.hを
#pragma unmanaged
int func(int num){
return num*2;
}
のように書き、Form.hで
#include "native_program.h"
(中略)
int num2 = func(50);
(後略)
のように呼び出しても、マネージコードでは呼び出せませんのようなエラーが出て上手くいきません。
1つのプロジェクト内で、ネイティブコードも書きながら、#pragma unmanagedを使って
コンパイルするというのは無理なのでしょうか?
http://www.atmarkit.co.jp/fdotnet/special/vcppinvista01/vcppinvista01_02.html
ここにあるようにdll化して呼び出すということをしないとダメなのでしょうか。
これだとデバッグが大変なので、1つのプロジェクト内やりたいのですが・・・・

よろしくお願いします。
2012/06/27(水) 10:57:39.47
include ってそこに書いたのと同じ意味になるんだがそれはわかってる?
2012/06/27(水) 13:42:46.79
>>530
小一時間考え、
#include "native_program.h" の下に #pragma unmanaged を入れたら通りました・・・お騒がせしました

ところで、func()は実際はクラスの中に入ってるのですが、
呼び出し側では、
Classname* classname;
classname->func();
のようにすればOKなのでしょうか。この2行はマネージコードの中に入ってるけど
特にnewとかしなくても上の一行だけでクラスのオブジェクト作られてるのかなと・・・
というか、このように書いたら動いたのでOKなのかなと思ってるのですが。
2012/06/27(水) 13:43:46.48
失礼、#pragma managedです。。。
書き間違いました^^;
2012/06/27(水) 14:15:48.48
オブジェクトは無いだろう。
thisポインタがNULLのまま
2012/06/27(水) 14:23:15.98
オブジェクトはないけど動いている・・・
ということは、実行ファイルを直接読んでるということか・・・
よくわからないし動いてるので気にしないことにします^^;

失礼しましたw
2012/06/27(水) 14:24:02.48
>>531
Classname classname;
classname.func();
ならOK
2012/06/27(水) 14:50:42.50
まあ素直にstaticつけようぜ
2012/06/27(水) 15:05:30.83
なんで動いてるか気持ち悪かったのでやっぱりnewとdelete追加しときましたw

>>535
それだとコンパイルする人がエラー出しますね

>>536
やっぱ暗黙的に静的インスタンス?みたいなの作られてて、それのポインタになるんですかね
実体がなかったら動くわけないし。
デバッガでみたらポインタは未定義の値みたいになってましたけど
2012/06/27(水) 15:12:22.35
仮想関数じゃねーんだから、実体があるとかどうとか関係無い。
単に関数呼んでるだけだ、未定義のthisポインタでな。
2012/06/27(水) 15:24:21.57
>>537
>実体がなかったら動くわけないし
ところがCやC++では動く。
速度重視のため、安全確保のための自動チェックなどは行われない。
そしてメンバ変数に代入すると何処とも知れないメモリアドレスを書き換えて
所謂セキュリティホールになったりする。
メモリアクセス違反で強制終了するのはまだ良い方。
2012/06/27(水) 15:30:07.51
>>539
いあいあ、実体というか、どこかに機械語のコードがなかったら動くわけないですよね?
その場所がわからないとうか、管理されてないというかんじなのかな?
OSが管理してて、そのOSによるということなのかなあ
2012/06/27(水) 15:35:31.60
しったかしてるから初心者みたいな勘違いしたままなんだよ
2012/06/27(水) 15:36:54.37
>>540
まず「ヒープ」「スタック」「コードセグメント」あたりの
基礎から勉強すべき
2012/06/27(水) 15:44:18.84
C++/CLIってC++と.NET両方の知識がある人向けだから
そうでない人はC#でP/Invokeを使った方がいいと思う。
2012/06/28(木) 01:46:27.01
今更だけど、pragma managed も push pop できたと思うよ。
2012/06/28(木) 09:51:50.05
まあヘッダに入れてるしC++勉強始めて3日くらいの知識でC++/CLIとごっちゃで勉強すると
後で困ると思うがなあ
2012/07/03(火) 11:14:40.00
VisualC++の入門書を買って来たらC++/CLIの本だったのは良い思い出・・・
2012/07/03(火) 14:15:43.34
「シー教えてくれ」と言われ見たらC#
2012/07/04(水) 11:10:26.99
そのときの「シー」は半音上がってたんだろうw
549デフォルトの名無しさん
垢版 |
2012/07/08(日) 14:06:13.60
>>548
うまいw
2012/07/13(金) 12:10:27.73
C++/CLI で暗黙のバッキングストア使うとき、get/setで異なるスコープにすることはできますか?
C# であれば public Hoge { get; protected set; } のような感じで。

ちなみに今使っているのはVS2008です。
2012/07/13(金) 21:51:43.58
出来るよ。

ref class Clazz
{
  property int XXX
  {
  private:
    void set(int iA);
  public:
    int get();
  }
};
2012/07/13(金) 22:09:27.40
>>551
ありがとー。
本体を書かなければ自動生成されるんですね。いわゆるWeekシンボルってやつかな。

>>550
× public Hoge { get; protected set; }
○ public int Hoge { get; protected set; }
2012/07/19(木) 19:16:48.08
XmlTextReaderでxmlファイルを読み込むとき,ファイルがあるかないかの判別はどうすればいいですか?
2012/07/19(木) 19:22:48.77
例外見ればいいだろ
555553
垢版 |
2012/07/19(木) 19:31:55.14
msdnにあるFileNotFoundExceptionを使うのでしょうか?
使い方がいまいちわかりません・・・
恐縮ですができればサンプルコードを書いていただけませんか?
XmlTextReader^ reader = gcnew XmlTextReader( "sample.xml" );
2012/07/19(木) 21:32:34.53
XmlTextReaderのコンストラクタを直接触るのは非推奨
try { XmlReader^ reader = XmlReader.Create( "sample.xml" ); }
catch (FileNotFoundException^ ex) { Console::WriteLine("ファイルが見つかりません。"); }
C++/CLIは君みたいな人が足を踏み入れるようなもんじゃないし
頑張ったところで特にメリットもない
今すぐC#かネイティブのC++へ移行することを強くお勧めする
557556
垢版 |
2012/07/19(木) 21:37:22.99
C#とごっちゃになってた
XmlReader::Createの間違い
558553
垢版 |
2012/07/19(木) 22:01:25.04
>>556-557
ご回答ありがとうございます 助かりました
基礎ができていないのは痛感しております・・・
もしおすすめの参考書があれば教えていただけると幸いです・・・
2012/07/19(木) 22:11:53.24
悪いことは言わん
どうしてもC++/CLIを使わないといけないのなら、まずはC#を覚えるのが近道だ
C#なら入門者向けの書籍やサイトなどもいくらでもあるし、
C++/CLIの.NETの部分はC#もどきの劣化版にすぎない。
560553
垢版 |
2012/07/20(金) 00:50:32.54
>>559
なるほど・・・
しかし今作っているプログラムを作り直す時間がありませんので
ひと段落してからC#の勉強をしたいと思います・・・
ありがとうございました.
2012/07/20(金) 10:49:26.48
なぁ、実際C++/CLIの利点て具体的にどうなの?
C++で作ったライブラリもユニコード使用でないとオーバーヘッドかかるし
.NET側にC++クラスのオブジェクトを入れるとポインタ使用になるし。
まぁ、パソコンも進化続けるから、アプリの重さも気にはなくなるだろうけど。
2012/07/20(金) 11:24:54.04
ホスト:アンマネージ、プラグイン:.NETの場合は、C++/CLIなしでやろうとすると
COMを経由してCLRをホストしたりとかクソ面倒臭い
.NETからC++のクラスを使いたい場合、C++/CLIではなくDllImportを使うとなると
いったんC向けのフラットなインターフェイスにラップしてやらないといけなくてクソ面倒臭い
どっちにしろC#とアンマネージC++を両方使う場合にのみ役に立つ
2012/08/02(木) 20:07:41.60
質問させて下さい。
visual studio 2005でC++/CLIを用いて開発を行なっています。
ref struct AA
{
 public:
  int a1;
}
refクラスの上記のような構造体を定義してそのオブジェクトを2つ作り、
AA a, aa;
a = aa;    (例なので初期化せずに代入しています)
とすると「error C2582; 'operator '=' 関数を 'AA' で使用できません」となってしまいます。
実際にはrefクラスの構造体を引数として渡したかったのですがC2664になってしまいビルドが通りませんでした。
そこで一番単純な構造体の代入コードを記述したところ、上記のようなエラーとなりあました。
いろいろ調べてみると、refクラスはコピーインスタンスとコピー代入演算子をデフォルトで自動生成しない
ということが原因かと考えたのですが対策が思いつきません。

refクラスの構造体の代入とコピーの方法をご教授いただければ幸いです。よろしくお願い致します。
2012/08/02(木) 20:16:58.19
で、値をコピーしたいの? 参照だけで良いの?
value struct AA じゃ駄目?
^は知ってる?
565563
垢版 |
2012/08/04(土) 11:12:00.62
>>564
レスありがとうございます。
私の勉強不足のため、クラスライブラリ側の宣言はref structで宣言しないとダメだと思い込んでいました。
しかも、クラスライブラリ以外のプロジェクトでも同様の結果になるため、勝手に環境の説明を省いてしまいました。
申し訳ありません。
ご指摘の通り、value structにすることで解決できました。ありがとうございました。
2012/08/07(火) 23:03:24.56
PathCombainのstd::string版ってないですかね?
2012/08/09(木) 09:35:42.88
この本って古本で定価の倍でも買う価値あります?

実践C++/CLI 極めるための基礎と実用テクニック
http://www.amazon.co.jp/dp/4797336277/

最近、DirectXをWPFから呼び出す必要が出てきて……
でも、VS2012と.NET4.0が出たときに
新しい本がいろいろ出版されるような気もしますよね……
2012/08/09(木) 12:10:48.40
2012は4.5だ
2012/08/09(木) 18:33:32.45
>>567
SlimDXを使うか、読めば足りるんじゃないか。
2012/08/10(金) 10:02:39.92
使いたいDirectXの機能によっても代わるよなぁ
2012/08/10(金) 13:32:29.83
> マイクロソフトから、お客様のアプリケーションがたくさんの人々の目に触れ、
> 試用および購入されるのをサポートする、新しい特典をお知らせいたします。
> MSDN サブスクライバーであるお客様は、1 回のご購入で 12 か月有効な
> Windows ストアおよび Windows Phone の開発者アカウントを取得すること
> ができます。

AzureはVLで買っても契約期間分使えるのに(厳密にいうと少し違うが)、
これはVL(2or3年)で買ってると悲しいな。
2012/08/10(金) 13:34:07.44
テラ誤爆…サーセン
2012/08/10(金) 14:19:24.98
http://toro.2ch.net/test/read.cgi/tech/1323588154/672
2012/08/11(土) 01:18:09.35
(;´д`)アアン
575すとら
垢版 |
2012/08/14(火) 03:35:57.72
VS2010でフォームアプリの勉強をしています。
unmanagedクラスで別スレッドにて不定期で呼ばれる関数から、
managedなフォームの内容を変更したいと考えています。

下記のようにコーディングしましたが、stackoverflow(InvokeRequiredがずっとtrueのため)
で動きません。。どなたか適切な方法を教えていただけないですか?
1.managedなformメソッドとしてform編集メソッド作成
2.スレッドセーフにするためInvokeでラップ
 参考:http://blogs.yahoo.co.jp/fireis_myblood/25643271.html
3.delegate->Marshal::GetFunctionPointerForDelegate()でポインタ化
4.unmanagedの不定期呼び出され関数に2の関数ポインタを設定
5.実行
2012/08/14(火) 04:28:26.47
Marshal::GetFunctionPointerForDelegate の返り値を CreateThread の第四引数に渡して別スレッドから呼んでみたけど、
別スレッドからの呼び出しでは InvokeRequired は true になって、そこで Invoke した先では false になったよ。
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況