facebook twitter hatena line google mixi email
★お気に入り追加


■ このスレッドは過去ログ倉庫に格納されています

おそらく、.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

ここまで見た
  • 2
  • ./1256645713/662
  • 2010/03/15(月) 09:45:45
ドキュメントの MSDN には、System::String(SByte*); て書いてあるけども、
System::String(char*); が正解ってことか?

それとも SByte が signed char ではなくて char てこと?それは無いような気が。

ちなみに、使ってる教科書のサンプルプログラムは8bitでは char* 配列を渡してる。

ここまで見た
  • 3
  •  
  • 2010/03/17(水) 19:44:10
厳密名の付け方が分かりません
検索しても意味不明なものしか引っかからない

ここまで見た
  • 4
  •  
  • 2010/03/17(水) 21:02:17
開発でつかわれてるのかな?
C++/CLIって。

ここまで見た
  • 5
  •  
  • 2010/03/17(水) 21:41:39
必要なら使われるだろ。
だからなんなんだ?

ここまで見た
  • 6
  •  
  • 2010/03/17(水) 22:37:29
>>3
LINKにある。
/KEYCONTAINER /KEYFILE

ここまで見た
  • 7
  •  
  • 2010/03/17(水) 22:45:13
というか必要な時だけ最小限使うもの
基本的に使わないほうがいい

ここまで見た
  • 8
  •  
  • 2010/03/18(木) 00:33:17
最近妙にお気に入り

ここまで見た
  • 9
  •  
  • 2010/03/18(木) 09:03:31
Managed C++でさえ一部で使われていた。

ここまで見た
  • 10
  •  
  • 2010/03/22(月) 19:23:41
フォームの中にあるテキストボックスの内容をmainとか関数とかから書き換えたいんだけど
どんな方法があるでしょうか?
今までは強引にチェックボックスにチェックが入ると
void test(System::Windows::Forms::TextBox^ tb_log_view);
こんな感じの関数呼び出してTextBoxを強引にわたして指定の処理して
テキストボックスにメッセージ表示させてたんだけど
何せ使い勝手が悪いので・・・

ここまで見た
  • 11
  •  
  • 2010/03/25(木) 01:29:18
String^使えばいいんちゃう?

ここまで見た
  • 12
  •  
  • 2010/03/25(木) 18:00:01
今、「Cで書かれたライブラリをC++/CLIでラッピング(DLL化)し、
C#で使おう」という目的に向けて、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#版を使ってます。

ここまで見た
  • 13
  •  
  • 2010/03/25(木) 18:34:20
>  static CHAR cUpdate; 
Cさえ理解していないのがよくわかる。

ここまで見た
  • 14
  •  
  • 2010/03/25(木) 18:45:45
うわ・・・・・
泣ける・・・・orz

回答有難うです

ここまで見た
  • 15
  •  
  • 2010/03/25(木) 18:53:51
突っ込みどころや怪しい箇所が多すぎて、どうしたいかが見えてこない(笑
配列はC++/CLIでアロケーションしていいのかとか。
C#でいう構造体はvalue class (or struct)であって、ref structはクラスだけどどっちにしたいのとか。

ここまで見た
  • 16
  • 12,14
  • 2010/03/25(木) 19:13:48
目的は、「Cで書かれたライブラリをC#で使う」事なのですが、
現状は、Cの方には手を加えないように、やる方法として、C++/CLIで
ラッピングするという手段があるという事なので、作業している次第。

そこで、構造体のポインタを戻り値としている関数はどう扱えば?と
思ってましたら、
http://ap.atmarkit.co.jp/bbs/core/fdotnet/17380
このような話をみつけたので、まずはref structでやってるという状況です。


ここまで見た
  • 17
  •  
  • 2010/03/25(木) 20:50:34
CのライブラリだったらC++/CLIなんか使わずにC#でDllImportすればいいような

ここまで見た
  • 18
  • 12,14
  • 2010/03/26(金) 09:55:14
>>17
説明不足でした。
(当然の疑問ですよね)

そのCのライブラリというのが、元がスタティックしか考慮されておらず、
DLL用にはなってなく(__declspec(dllexport)のような記載は一切なし)、
選択肢として
1 Cのソースをdll対応に修正(__declspecを全関数に追加)
2 元のCには手を加えず、新しくラッパーを作る

があり、今後もCの方は勝手にバージョンが上がっていくので、
それなら、元のソースに手を加えない方向でやろうとなった次第です。


ここまで見た
  • 19
  •  
  • 2010/03/26(金) 10:26:08
だからってそのラッパーをC++/CLIで書く必要はないだろ
Cで薄ーいラッパー書いて普通のネイティブDLLとしてコンパイルすればおk
C++のライブラリとなると面倒だけどそうでないならC++/CLIはできるだけ避けたほうが賢明

ここまで見た
  • 20
  • 12,14
  • 2010/03/26(金) 12:05:28
>>19
その手がありましたか!
C#でDllImportして、
DLL関数に渡す構造体、DLL関数から受け取る構造体は
[StructLayout(LayoutKind.Sequential)]を用いてC#側に定義して
やりとりするという事ですね。

試してみます

ここまで見た
  • 21
  •  
  • 2010/04/25(日) 20:06:11
【初心者歓迎】C/C++室 から誘導されてきました。

Form1とForm2があり、Form1からForm2を呼び出すようにしています。
また、Form2に配置したボタンを押すと関数が呼び出されて、所望の処理をするようにしています。
以下の2点について教えてください。

1.関数内の処理の進捗をForm2内のLabelやProgressBarに表示したいです。
2.Form2からForm1を操作したい(Form2のボタンを押すとForm1/Form2ともに終了するようにしたい)です。

両方ともポインタを使えば出来そうな気がするのですが、例えば2.の方ではForm2を指すポインタの宣言の仕方が
わからないです。

よろしくお願いします。


ここまで見た
  • 22
  •  
  • 2010/04/25(日) 20:24:49
>>21
ポインタじゃなくて参照になる。
Form2^ form2;

ここまで見た
  • 23
  •  
  • 2010/04/25(日) 20:26:28
>>21
動くかどうかは試してない。

【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();
}


ここまで見た
  • 24
  • 21
  • 2010/04/25(日) 23:09:54
>>22>>23
ありがとうございます。
残念ながらうまくいかないです。

環境は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();にあたる部分)がコンパイルエラーになってしまいます。



ここまで見た
  • 25
  •  
  • 2010/04/27(火) 01:31:54
なんでこういう意味での初心者がC++/CLIなんてマニアックな言語触ってるんだろう……?

> 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で確認

ここまで見た
  • 26
  •  
  • 2010/06/07(月) 09:58:49
C++/CLIだと、Cのランタイム例外のハンドリングが出来ない臭いんだけど、どうすれば良いんだろう…
ハンドラ設定してるのに動いてくれない
例えば_tcsftime(..., L"%h", ...);みたいなやつ

※普通の例外じゃないんで、マネージand/orネイティブでもtry catch出来ない

ここまで見た
  • 27
  •  
  • 2010/06/09(水) 20:43:17
そもそもCRTが例外なんて投げないはずだが

> 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 ) );
>     だからデバッグ時だけの話じゃん。

ここまで見た
  • 28
  •  
  • 2010/06/10(木) 10:35:20
>>27
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;
}


ここまで見た
  • 29
  •  
  • 2010/06/10(木) 13:07:44
ハンドラ設定ってなんだ普通に_set_invalid_parameter_handlerで呼んでくれたが

ここまで見た
  • 30
  •  
  • 2010/06/14(月) 22:16:23
SerialPortクラスを使ってデータを受信する際、
・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]);
}
}


ここまで見た
  • 31
  •  
  • 2010/06/26(土) 12:09:02
マネージクラスのインスタンスをグローバルスコープっぽく参照する方法ないの?
全コンストラクタでやりとりするようなマンドクセ方法がいやだ

ここまで見た
  • 32
  •  
  • 2010/06/26(土) 15:55:49
クラスの静的メンバに入れとけばいいだけ

ここまで見た
  • 33
  •  
  • 2010/06/27(日) 16:28:42
あと public static ね

ここまで見た
  • 34
  •  
  • 2010/08/05(木) 23:46:40
C++/CLIに書き換えてる奇特なものです

char www[100];
char* ptr;
ptr = www + i;

array<char>^ www = gcnew array<char>(100);
array<char>^ ptr;
ptr = www + i; ← ?

?の部分をご教授くださいm(_ _)m

ここまで見た
  • 35
  •  
  • 2010/08/06(金) 00:53:22
CLI配列はポインタじゃないから無理

ここまで見た
  • 36
  •  
  • 2010/08/06(金) 10:21:40
pin_ptr してもいいけどさ、www[i] で駄目な理由は何なの?

ここまで見た
  • 37
  •  
  • 2010/08/07(土) 08:14:59
C++の感覚なら毎回[i+a]としないで最初からオフセット付けときたいのは当然だろ
無理なので常にwwwとiをセットにして持ちまわるのが普通
メソッドの引数にもオフセットを指定できるようにする

ここまで見た
  • 38
  •  
  • 2010/08/07(土) 22:43:16
perlのように return a, b できるようにしてくんないかな



ここまで見た
  • 39
  •  
  • 2010/08/08(日) 12:07:55
.NET4ではTuple型自体は導入されたのでC#やVBでは将来的に
言語レベルでサポートされる可能性はある。
C++/CLIはほぼ見捨てられてるので期待するだけ無駄。

ここまで見た
  • 40
  •  
  • 2010/08/17(火) 21:49:08
>>34
array<char>^ www = gcnew array<char>(100);
interior_ptr<char> ptr;
ptr = &www[0] + i;

ここまで見た
  • 41
  •  
  • 2010/08/21(土) 06:53:22
VC2010 EEを使用しています。

RS-232Cで通信を行い、プログラムを終了させようとして
this->Close();
を行うと、エラーメッセージも出ないままプログラムが固まってしまいます。

ポートを閉じてないことが原因かと思い、
serialPort1->Close();
を実行してみたところ、今度はここで同じように固まってしまいました。

http://vsug.jp/tabid/63/forumid/46/postid/9991/scope/posts/Default.aspx
を、参考に、BeginInvokeを使用していますが、ダメでした。

この場合、どこを見れば良いのでしょうか?
よろしくお願いします。

ここまで見た
  • 42
  •  
  • 2010/09/18(土) 16:16:15
画像処理を行いたいのですが、
Bitmap、Image、Graphic・・・どのコンポーネントを使うのがお得なのでしょうか

ここまで見た
  • 43
  •  
  • 2010/09/18(土) 16:36:42
>>42
どんな画像処理をするかが分からないと、
えらべないと思われます

ここまで見た
  • 44
  • 42
  • 2010/09/18(土) 16:48:33
カラー画像をモノクロにしたり、コントラストかけたり、拡大縮小したりの初歩的なことがしたいです。
あと、今のところはCUIで行いたいです。

ここまで見た
  • 45
  •  
  • 2010/09/18(土) 18:01:22
>>44
俺はあまり詳しくないが、
ぐぐると
ttp://msdn.microsoft.com/ja-jp/academic/cc998604.aspx
ここで
Bitmap クラスを利用することにより、画像に対してピクセル単位で様々な処理を行うことができます
と書いてある
.netのクラスを使うなら、おそらくやりたいことはこういうことだろう


ここまで見た
  • 46
  •  
  • 2010/09/18(土) 23:40:29
Bitmap使ってみたけれど、画像の保存の仕方がわからない・・・
WriteBitmap("C:\\・・・",data)とかdata.Save(・・・)ってな感じでできないのかな

ここまで見た
  • 47
  •  
  • 2010/09/18(土) 23:43:33
普通にSaveメソッドあるだろ

ここまで見た
  • 48
  •  
  • 2010/09/19(日) 05:14:50
ホントだ。ごめん、見逃してたわ。

ここまで見た
  • 49
  •  
  • 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

ここまで見た
  • 50
  •  
  • 2010/09/20(月) 07:25:44
>>49
test.jpegはちゃんとプロジェクトファイルと同じ階層にある?

余計なお世話かも知れないが、.netでやるなら
C#で作ったほうが楽なんじゃないだろうか・・・
わざわざマイナーな環境で挑戦するよりもいいと思うんだが

お絵かきランド
フリックゾンビ
ここまで見た

★お気に入り追加

このページを共有する
facebook twitter hatena line google mixi email
おすすめワード