くだすれC++/CLI(初心者用)part2
■ このスレッドは過去ログ倉庫に格納されています
0001./1256645713/662
2010/03/15(月) 09:41:19C++/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
0004デフォルトの名無しさん
2010/03/17(水) 21:02:17C++/CLIって。
0005デフォルトの名無しさん
2010/03/17(水) 21:41:39だからなんなんだ?
0006デフォルトの名無しさん
2010/03/17(水) 22:37:29LINKにある。
/KEYCONTAINER /KEYFILE
0007デフォルトの名無しさん
2010/03/17(水) 22:45:13基本的に使わないほうがいい
0008デフォルトの名無しさん
2010/03/18(木) 00:33:170009デフォルトの名無しさん
2010/03/18(木) 09:03:310010デフォルトの名無しさん
2010/03/22(月) 19:23:41どんな方法があるでしょうか?
今までは強引にチェックボックスにチェックが入ると
void test(System::Windows::Forms::TextBox^ tb_log_view);
こんな感じの関数呼び出してTextBoxを強引にわたして指定の処理して
テキストボックスにメッセージ表示させてたんだけど
何せ使い勝手が悪いので・・・
0011デフォルトの名無しさん
2010/03/25(木) 01:29:180012デフォルトの名無しさん
2010/03/25(木) 18:00:01C#で使おう」という目的に向けて、Cのライブラリをラッピング中ですなのですが、構造体で悩んでます。
C++/CLI側でC#側に「構造体の配列」を返す関数が見せてるのですが、実行すると思ったように動きません。
C++/CLI側
[宣言]
public ref struct SampleStruct {
static CHAR cUpdate;
};
static array<SampleStruct^>^ pstSample = gcnew array<SampleStruct^>(10);
関数
array<SampleStruct^>^ hogehoge(){
if(pstSample[0] == nullptr ){
for(int i=0; i<10; i++ ){
pstSample[i] = gcnew (SampleStruct);
}
}
pstSample[2]->cUpdate = 2;
return pstSample;
}
C#側
SampleStruct[] stTest = new SampleStruct[10];
stTest = LIBSAMPLE.hogehoge();
ここで、stTest[0].cUpdateからstTest[9].cUpdateまでを見ると
全部2が入っております。(本当は[2].cUpdateだけ2が入っていて欲しい)
どこが原因か分かりますでしょうか?
OS:XP
環境:VS2008 ExpressのC++版とC#版を使ってます。
0013デフォルトの名無しさん
2010/03/25(木) 18:34:20Cさえ理解していないのがよくわかる。
0014デフォルトの名無しさん
2010/03/25(木) 18:45:45泣ける・・・・orz
回答有難うです
0015デフォルトの名無しさん
2010/03/25(木) 18:53:51配列はC++/CLIでアロケーションしていいのかとか。
C#でいう構造体はvalue class (or struct)であって、ref structはクラスだけどどっちにしたいのとか。
001612,14
2010/03/25(木) 19:13:48現状は、Cの方には手を加えないように、やる方法として、C++/CLIで
ラッピングするという手段があるという事なので、作業している次第。
そこで、構造体のポインタを戻り値としている関数はどう扱えば?と
思ってましたら、
http://ap.atmarkit.co.jp/bbs/core/fdotnet/17380
このような話をみつけたので、まずはref structでやってるという状況です。
0017デフォルトの名無しさん
2010/03/25(木) 20:50:34001812,14
2010/03/26(金) 09:55:14説明不足でした。
(当然の疑問ですよね)
そのCのライブラリというのが、元がスタティックしか考慮されておらず、
DLL用にはなってなく(__declspec(dllexport)のような記載は一切なし)、
選択肢として
1 Cのソースをdll対応に修正(__declspecを全関数に追加)
2 元のCには手を加えず、新しくラッパーを作る
があり、今後もCの方は勝手にバージョンが上がっていくので、
それなら、元のソースに手を加えない方向でやろうとなった次第です。
0019デフォルトの名無しさん
2010/03/26(金) 10:26:08Cで薄ーいラッパー書いて普通のネイティブDLLとしてコンパイルすればおk
C++のライブラリとなると面倒だけどそうでないならC++/CLIはできるだけ避けたほうが賢明
002012,14
2010/03/26(金) 12:05:28その手がありましたか!
C#でDllImportして、
DLL関数に渡す構造体、DLL関数から受け取る構造体は
[StructLayout(LayoutKind.Sequential)]を用いてC#側に定義して
やりとりするという事ですね。
試してみます
0021デフォルトの名無しさん
2010/04/25(日) 20:06:11Form1とForm2があり、Form1からForm2を呼び出すようにしています。
また、Form2に配置したボタンを押すと関数が呼び出されて、所望の処理をするようにしています。
以下の2点について教えてください。
1.関数内の処理の進捗をForm2内のLabelやProgressBarに表示したいです。
2.Form2からForm1を操作したい(Form2のボタンを押すとForm1/Form2ともに終了するようにしたい)です。
両方ともポインタを使えば出来そうな気がするのですが、例えば2.の方ではForm2を指すポインタの宣言の仕方が
わからないです。
よろしくお願いします。
0022デフォルトの名無しさん
2010/04/25(日) 20:24:49ポインタじゃなくて参照になる。
Form2^ form2;
0023デフォルトの名無しさん
2010/04/25(日) 20:26:28動くかどうかは試してない。
【Form1.h】
ref class Form1 {
public: System::Void Form1Func() {〜}
private: System::Void Form2Func();
private: System::Void Form1_KeyDown(〜) {Form2Func();}
}
【Form1.cpp】
#include "Form1.h"
#include "Form2.h"
System::Void Form1::Form2Func(){
Form2^ form2 = safe_cast<Form2^>(Application::OpenForms["Form2"]);
form2->Form2Func();
}
【Form2.h】
ref class Form2 {
public: System::Void Form2Func() {〜}
private: System::Void Form1Func();
private: System::Void Form2_KeyDown(〜) {Form1Func();}
}
【Form2.cpp】
#include "Form1.h"
#include "Form2.h"
System::Void Form2::Form1Func()
{
Form1^ form1 = safe_cast<Form1^>(Application::OpenForms["Form1"]);
form1->Form1Func();
}
002421
2010/04/25(日) 23:09:54ありがとうございます。
残念ながらうまくいかないです。
環境はVS2005 C++ WinXP SP3
Form1(親フォーム)からはForm2.hをインクルードして
Form2^ frm = gcnew Form2();
frm->ShowDialog();
とできるのですが、Form.hではForm1.hをインクルードすると循環参照になってしまうようでエラーになります。
また、Form2.h内で関数宣言だけしてForm2.cpp内でForm1.hをインクルードして実行部分を書こうとしましたが
Form2.h内の関数宣言(>>23のprivate: System::Void Form1Func();にあたる部分)がコンパイルエラーになってしまいます。
0025デフォルトの名無しさん
2010/04/27(火) 01:31:54> Form2に配置したボタンを押すと関数が呼び出されて
> 1.関数内の処理の進捗をForm2内のLabelやProgressBarに表示したいです。
Form1関係ないよね? Form2が勝手にやってろって話
> 2.Form2からForm1を操作したい(Form2のボタンを押すとForm1/Form2ともに終了するようにしたい)です。
Form1がForm2を作ったとき、Form2のFormClosedイベントに引っかけるとかすればいいんじゃね?
// Form1内のForm2を表示させる処理
Form2^ form = gcnew Form2();
form->FormClosed += gcnew FormClosedEventHandler(this, &Form1::OnForm2Closed);
form->Show();
// Form1内で定義
private: void OnForm2Closed(Object^ sender, FormClosedEventArgs^ e) {
this->Close();
}
×アイコンで閉じたときはForm1は閉じない、ボタン押したときだけとかなら
Form2にCloseWithParentみたいなプロパティ用意して
表示させるときのForm2^はメンバ変数に保持しておいて
OnForm2Closedで確認
0026デフォルトの名無しさん
2010/06/07(月) 09:58:49ハンドラ設定してるのに動いてくれない
例えば_tcsftime(..., L"%h", ...);みたいなやつ
※普通の例外じゃないんで、マネージand/orネイティブでもtry catch出来ない
0027デフォルトの名無しさん
2010/06/09(水) 20:43:17> 727 :デフォルトの名無しさん[sage]:2008/07/03(木) 13:51:22
> なんで、VC++2008の、strftime _tcsftimeは、
> 書式に無い文字を渡すと例外終了するのかなあ。
> 単に無視してくれりゃいいのに。
> 自前でパースしてから、渡してやるしか無いのかな。
> 729 :デフォルトの名無しさん[sage]:2008/07/03(木) 14:11:02
> ちょっと見てみたけど
> _ASSERTE( ( "Invalid format directive" , 0 ) );
> だからデバッグ時だけの話じゃん。
0028デフォルトの名無しさん
2010/06/10(木) 10:35:20つ http://msdn.microsoft.com/ja-jp/library/ksazx244(v=VS.80).aspx
試してみると早いかも…
int main(array<System::String ^> ^args)
{
Console::WriteLine(L"Hello World");
tm tmNow;
__time64_t tNow;
TCHAR sz[20];
try
{
_time64(&tNow);
_localtime64_s(&tmNow, &tNow);
_tcsftime(sz, 20, L"%h", &tmNow);
}
catch (...)
{
Console::WriteLine("error!");
}
Console::ReadLine();
return 0;
}
0029デフォルトの名無しさん
2010/06/10(木) 13:07:440030デフォルトの名無しさん
2010/06/14(月) 22:16:23・SerialPort::Data_Receivedイベントで受信
・受信データはQueueクラス経由でメインスレッドから受信
・メインスレッドでは、あるバイト数を数秒以内に受信できない場合タイムアウト
を、実装したいのですが、タイムアウト処理はどのように記述したら良いのでしょうか?
// Data_Receivedイベント
private: System::Void serialPort_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e)
{
int length = serialPort->BytesToRead;
array<unsigned char>^ buffer = gcnew array<unsigned char>(length);
serialPort->Read(buffer, 0, length);
Queue^ sync_queue = Queue::Synchronized(m_queue);
for (int i = 0; i < length; i++)
{
sync_queue->Enqueue(buffer[i]);
}
}
0031デフォルトの名無しさん
2010/06/26(土) 12:09:02全コンストラクタでやりとりするようなマンドクセ方法がいやだ
0032デフォルトの名無しさん
2010/06/26(土) 15:55:490033デフォルトの名無しさん
2010/06/27(日) 16:28:420034デフォルトの名無しさん
2010/08/05(木) 23:46:40char www[100];
char* ptr;
ptr = www + i;
array<char>^ www = gcnew array<char>(100);
array<char>^ ptr;
ptr = www + i; ← ?
?の部分をご教授くださいm(_ _)m
0035デフォルトの名無しさん
2010/08/06(金) 00:53:220036デフォルトの名無しさん
2010/08/06(金) 10:21:400037デフォルトの名無しさん
2010/08/07(土) 08:14:59無理なので常にwwwとiをセットにして持ちまわるのが普通
メソッドの引数にもオフセットを指定できるようにする
0038デフォルトの名無しさん
2010/08/07(土) 22:43:160039デフォルトの名無しさん
2010/08/08(日) 12:07:55言語レベルでサポートされる可能性はある。
C++/CLIはほぼ見捨てられてるので期待するだけ無駄。
0040デフォルトの名無しさん
2010/08/17(火) 21:49:08array<char>^ www = gcnew array<char>(100);
interior_ptr<char> ptr;
ptr = &www[0] + i;
0041デフォルトの名無しさん
2010/08/21(土) 06:53:22RS-232Cで通信を行い、プログラムを終了させようとして
this->Close();
を行うと、エラーメッセージも出ないままプログラムが固まってしまいます。
ポートを閉じてないことが原因かと思い、
serialPort1->Close();
を実行してみたところ、今度はここで同じように固まってしまいました。
http://vsug.jp/tabid/63/forumid/46/postid/9991/scope/posts/Default.aspx
を、参考に、BeginInvokeを使用していますが、ダメでした。
この場合、どこを見れば良いのでしょうか?
よろしくお願いします。
0042デフォルトの名無しさん
2010/09/18(土) 16:16:15Bitmap、Image、Graphic・・・どのコンポーネントを使うのがお得なのでしょうか
0043デフォルトの名無しさん
2010/09/18(土) 16:36:42どんな画像処理をするかが分からないと、
えらべないと思われます
004442
2010/09/18(土) 16:48:33あと、今のところはCUIで行いたいです。
0045デフォルトの名無しさん
2010/09/18(土) 18:01:22俺はあまり詳しくないが、
ぐぐると
ttp://msdn.microsoft.com/ja-jp/academic/cc998604.aspx
ここで
Bitmap クラスを利用することにより、画像に対してピクセル単位で様々な処理を行うことができます
と書いてある
.netのクラスを使うなら、おそらくやりたいことはこういうことだろう
0046デフォルトの名無しさん
2010/09/18(土) 23:40:29WriteBitmap("C:\\・・・",data)とかdata.Save(・・・)ってな感じでできないのかな
0047デフォルトの名無しさん
2010/09/18(土) 23:43:330048デフォルトの名無しさん
2010/09/19(日) 05:14:500049デフォルトの名無しさん
2010/09/20(月) 03:53:30--- プログラム ---
#include "stdafx.h"
using namespace System;
using namespace System::Drawing;
int main(array<System::String ^> ^args){
Bitmap^ image = gcnew Bitmap("test.jpeg");
image->SetPixel(0,0,Color::Black); ←ここでなぜかエラー起きます
image->Save("test2.bmp");
return 0;
}
--- エラー内容 ---
ハンドルされていない例外: System.ArgumentException: 使用されたパラメータが有効ではありません。
場所 System.Drawing.Bitmap..ctor(String filename)
場所 main(String[] args) 場所 c:\documents and settings\***\デスクトップ\test\test.cpp:行 10
場所 mainCRTStartupStrArray(String[] arguments) 場所 f:\dd\vctools\crt_bld\self_x86\crt\src\mcrtexe.cpp:行 309
0050デフォルトの名無しさん
2010/09/20(月) 07:25:44test.jpegはちゃんとプロジェクトファイルと同じ階層にある?
余計なお世話かも知れないが、.netでやるなら
C#で作ったほうが楽なんじゃないだろうか・・・
わざわざマイナーな環境で挑戦するよりもいいと思うんだが
0051デフォルトの名無しさん
2010/09/20(月) 08:08:59落ちてる場所は、その上の行だぞ。
0052デフォルトの名無しさん
2010/09/20(月) 11:32:08初心者が質問するたびに使うなと勧められる
0053デフォルトの名無しさん
2010/09/20(月) 13:44:55ありがとう。jpegじゃなくてjpgだったという凡ミスしていたことに気づけたわ
・・・一度C#に浮気してみる
0054デフォルトの名無しさん
2010/09/20(月) 13:53:46嫌われているというか、言語自体が初心者お断りだからな
初心者が無謀なことしようとしていたら、そりゃ止めるだろう
0055デフォルトの名無しさん
2010/09/20(月) 14:01:21使わなくていいなら使いたくない。
0056デフォルトの名無しさん
2010/09/20(月) 15:01:38MDI作るときどうするかとか
ちょっとしたことの逆引きがネット上で全く出てこない
ようやくOpenGL表示できるようになって
C++の頃の遺産をつかえると思ったのに
0057デフォルトの名無しさん
2010/09/20(月) 16:33:26なにもかもC++/CLIで済ませようとしないことをお勧めする
0058デフォルトの名無しさん
2010/09/21(火) 02:27:48ただ何故かこの言語とのファーストコンタクトというか接し方が
一言入れておかないと不幸にしかならなそうな人が多いのよね
0059デフォルトの名無しさん
2010/09/21(火) 09:55:56こういうのがあるから「Visual C++ 2008 で簡単GUIプログラミング」みたいな勘違い本やサイトが出て初心者が道を間違える
0060デフォルトの名無しさん
2010/09/21(火) 23:18:00C++の文法がある程度使えて
フォームデザインが総合開発環境上で扱えて
至れり尽くせりじゃん、と思ってとっかかりました
現実は情報が全く無く
よくわからないクラスとかいっぱいあって
解説も無くて
どうしようと途方にくれていましたが、QTとかよりは
導入コストも再勉強のコストも無いだろうと信じて使ってます。
だって、CやC++だとGUI作るの辛いんだもん
っていう理由だとダメですか
0061デフォルトの名無しさん
2010/09/21(火) 23:32:23マネージ部分はC++とは直接関係なくて学び直し必要だし
それなら素直にC#
C#2.0の範囲までなら多分C++/CLIより簡単だし
サンプルも多いし将来WPF/Silverlightとかにも応用できるし
C#やっとけば逆にC++/CLIを橋渡し用ぐらいなら書けるようになるし
0062デフォルトの名無しさん
2010/09/27(月) 13:44:310063デフォルトの名無しさん
2010/09/27(月) 14:03:20それを一応形にできたところは評価できる。
0064デフォルトの名無しさん
2010/09/27(月) 19:28:250065デフォルトの名無しさん
2010/09/27(月) 19:37:100066デフォルトの名無しさん
2010/09/28(火) 02:31:06//////////Form1_Load//////////
HANDLE hMap;
LPVOID lpBuf;
hMap=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,1024,L"View");
if(hMap==NULL){Form::Close();}
lpBuf=MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0,0,0);
if(lpBuf==NULL){Form::Close();}
if(GetLastError()==ERROR_ALREADY_EXISTS){//すでに同じ名前のオブジェクトが存在する
lpBuf=Environment::GetCommandLineArgs();//コマンドラインから取得//ここでエラー
///////////ここまで/////////////
つまり二重起動時に共有メモリを使いたいのですが、どうしてもできません。
先人方どんなことでもいいので教えてくだせえ。
0067デフォルトの名無しさん
2010/09/28(火) 02:40:230068デフォルトの名無しさん
2010/09/28(火) 02:51:50> lpBuf=Environment::GetCommandLineArgs();//コマンドラインから取得//ここでエラー
コードの方はarray<String^>^からLPVOIDに変換したいように見える
0069デフォルトの名無しさん
2010/09/28(火) 03:19:272008 Express Editionを使っていまして・・・ヘッダーがないらしいです。
http://www.codeguru.com/forum/showthread.php?t=468408
>>68
コマンドライン引数を得た後、array<String^>^に変換しようと思ったのです。
宣言時からarray<String^>^だとMapViewOfFileでつまずいちゃうので・・・。
どちらにせよ、コマンドライン引数を得た後、
共有メモリarray<String^>^として反映できればいいのですが。
0070デフォルトの名無しさん
2010/09/28(火) 03:50:07そもそもLoadイベントなんかでやる処理には見えないけど(mainでやることだろ)
共有メモリにString^を書き込みたいのなら
> ttp://www.codeguru.com/forum/showthread.php?t=468408
のリンク先にString^をポインタに変換する方法が載ってるからmemcpyなりなんなりすればいい
複数の文字列を書き込む必要があるなら\0なりなんなりで区切る
0071デフォルトの名無しさん
2010/09/29(水) 06:10:09とにかく二重起動時にコマンドライン引数を渡すことができました!
皆様、貴重なアドバイスをありがとねん
0072デフォルトの名無しさん
2010/10/03(日) 12:39:42safe_cast :型が合わないと例外が発生、実行コスト中
dynamic_cast:型が合わないとNULLを返す、実行コスト大
static_cast :型が合わなくても何もしない、実行コスト小
この認識であってますか?
0073デフォルトの名無しさん
2010/10/03(日) 16:11:05static_castが速くなるのはダウンキャストの場合だけ。静的に解決できる場合はsafe_castと同じ。
0074デフォルトの名無しさん
2010/10/03(日) 20:39:28いまさらだけど、.NET Framework 4以降ならMemoryMappedFileクラスを使えばいいと思うよ。
0075デフォルトの名無しさん
2010/10/03(日) 20:52:42公式の説明でもパフォーマンスをえらく強調してるが、
そのためにわざわざ検証不能コードにしてまでやるほどのものなのかと
0076デフォルトの名無しさん
2010/10/08(金) 20:22:23>どうやらそれらは、レガシC++アプリケーションをWindows Phoneに移植したいと考えている多くの開発者にとって、C++/CLIは、ベストなルートに見えるのであろう。
地獄への道は善意で舗装されている
0077デフォルトの名無しさん
2010/10/08(金) 20:28:080078デフォルトの名無しさん
2010/10/08(金) 20:52:06Silverlightで使える範囲のC++/CLIはC++とは全く互換性なくてただの汚いC#なんだけど
0079デフォルトの名無しさん
2010/10/08(金) 21:47:310080デフォルトの名無しさん
2010/10/08(金) 22:05:210081デフォルトの名無しさん
2010/10/09(土) 21:36:15画像の場合ピクチャボックスみたいな感じに楽に音楽再生させたいのだけど
0082デフォルトの名無しさん
2010/10/10(日) 23:03:16.NET使ってもできる
どちらにしてもC++/CLIとは直接関係ない話
0083デフォルトの名無しさん
2010/10/11(月) 00:46:33これ絶対初心者向けじゃない気がする
0084デフォルトの名無しさん
2010/10/11(月) 00:49:57絶対初心者向けではない、その通りだ。
0085デフォルトの名無しさん
2010/10/11(月) 06:02:46俺みたいな勘違い君が集まるから
スレタイ変えると平和になる気がする
0086デフォルトの名無しさん
2010/10/11(月) 11:40:19「C++(非CLI)でアプリを作っているが、.NETのライブラリを使って音を鳴らしたい」
→そこだけC++/CLIを部分的に使おう
という風に特別な意図を持って言語であって、
>>81のような質問が出てくる時点でC++/CLIを使うのは間違っている
0087デフォルトの名無しさん
2010/10/11(月) 12:08:450088デフォルトの名無しさん
2010/10/11(月) 13:10:090089デフォルトの名無しさん
2010/10/11(月) 15:50:17C++/CLIの初心者向けのスレなんだよなw
0090デフォルトの名無しさん
2010/10/11(月) 16:27:401) C++習得レベル一定以上
2) .NET習得レベル一定以上
だからな
0091デフォルトの名無しさん
2010/10/12(火) 02:47:19みんな言うように初心者が使う物じゃないね。
0092デフォルトの名無しさん
2010/10/12(火) 15:18:47どうしても必要なときにちょっと調べてその場が凌げれば充分
0093デフォルトの名無しさん
2010/10/12(火) 18:55:470094デフォルトの名無しさん
2010/10/12(火) 19:17:34アンマネージとマネージの境界は常に意識する必要がある。
0095デフォルトの名無しさん
2010/10/12(火) 20:52:46Express Editionだと実行中のプロセスにアタッチできるのが
C++しかないってのも使ってる理由のひとつ。
0096デフォルトの名無しさん
2010/10/27(水) 21:11:21簡単GUIプログラミング!みたいな見事な勘違い記事だった。騙されて道を誤る初心者が不憫でならない。
0097デフォルトの名無しさん
2010/10/30(土) 18:38:530098デフォルトの名無しさん
2010/10/31(日) 02:19:240099デフォルトの名無しさん
2010/11/02(火) 23:54:010100デフォルトの名無しさん
2010/11/02(火) 23:59:30CLI拡張の部分だけでも言語仕様書の量がC#並み
0101デフォルトの名無しさん
2010/11/03(水) 00:03:310102デフォルトの名無しさん
2010/11/03(水) 04:25:150103デフォルトの名無しさん
2010/11/03(水) 16:45:49なんとなくこんな感じ、って思い描いたものが
1行で組みあがるくらいに
なるわけねぇ
■ このスレッドは過去ログ倉庫に格納されています