質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
C++/CLI

C++/CLIは、.NET Frameworkの共通言語基盤であるCLI向けにC++を拡張したプログラム言語です。前身のC++マネージ拡張と比較するとシンプルで分かりやすい構文になっており、高い可読性を持ちます。

Q&A

解決済

1回答

2399閲覧

C++定数の構造体配列をC++/CLIに変更する方法

JanTh1989

総合スコア87

C++/CLI

C++/CLIは、.NET Frameworkの共通言語基盤であるCLI向けにC++を拡張したプログラム言語です。前身のC++マネージ拡張と比較するとシンプルで分かりやすい構文になっており、高い可読性を持ちます。

0グッド

0クリップ

投稿2019/05/23 01:23

編集2019/05/23 01:59

前提

現在C++ヘッダをC++/CLIヘッダに変換を行っています。
CString型をString型にしてみたり、CArray型をList型にしてみたりなどなどをしています。
constの構造体配列の変更も同様に試みています。
コードは以下です。

<旧コード>

C++

1enum E_DATATYPE 2{ 3 E_DATATYPE_INT, 4 E_DATATYPE_CHAR, 5 E_DATATYPE_STRING 6}; 7 8namespace DataManage 9{ 10 typedef struct _ST_DATATYPE { 11 E_DATATYPE eDataType; 12 CString sDataName; 13 } ST_DATATYPE, *PST_DATATYPE; 14} 15 16const DataManage::ST_DATATYPE C_DATATYPE_LIST[] = 17{ 18 {E_DATATYPE_INT, _T("INT")}, 19 {E_DATATYPE_CHAR, _T("CHAR")}, 20 {E_DATATYPE_STRING, _T("STRING")}, 21};

<作ってみたコード>

C++

1enum E_DATATYPE 2{ 3 E_DATATYPE_INT, 4 E_DATATYPE_CHAR, 5 E_DATATYPE_STRING 6}; 7 8namespace DataManage 9{ 10 ref struct ST_DATATYPE { 11 E_DATATYPE eDataType; 12 String^ sDataName; 13 }; 14} 15 16const cli::array<DataManage::ST_DATATYPE^>^ C_DATATYPE_LIST = 17{ 18 {gcnew ST_DATATYPE(E_DATATYPE_INT, _T("INT"))}, 19 {gcnew ST_DATATYPE(E_DATATYPE_CHAR, _T("CHAR"))}, 20 {gcnew ST_DATATYPE(E_DATATYPE_STRING, _T("STRING"))}, 21};

質問

"作ってみたコード"のcli::array定義で、以下のエラーが発生しました。
・「静的ストレージ存続期間のある変数にハンドルや追跡参照型を指定することはできません」
・「関数呼び出しの引数が多すぎます」。
こちらについて対処する方法はあるのでしょうか?

また、そもそも初期化子で対応すること自体は可能なのでしょうか?

試してみたこと

・List型に変更
⇒こちらはCLI以外で初期化子禁止が出てしまい断念しました。

開発環境

Visual Studio 2015 Professional
.NET4.6

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

グローバルにrefクラスのインスタンスを持つのは無理だった気がします。

代わりに、refクラスの静的メンバとして宣言することはできるはずです。
例えば

C++

1ref class C_DATATYPE_LIST_WRAPPER 2{ 3public: 4 static cli::array<DataManage::ST_DATATYPE^>^ C_DATATYPE_LIST = gcnew cli::array<DataManage::ST_DATATYPE^> 5 { 6 gcnew DataManage::ST_DATATYPE(E_DATATYPE_INT, _T("INT")), 7 gcnew DataManage::ST_DATATYPE(E_DATATYPE_CHAR, _T("CHAR")), 8 gcnew DataManage::ST_DATATYPE(E_DATATYPE_STRING, _T("STRING")), 9 }; 10}; 11 12... 13 14C_DATATYPE_LIST_WRAPPER::C_DATATYPE_LIST[0]->sDataName

他の手段としては、C++のデータのラッパークラスを用意するとか

C++

1namespace DataManage 2{ 3 ref struct ST_DATATYPE_REF { // 新しく追加する 4 public: 5 ST_DATATYPE_REF(E_DATATYPE dataType, CString str) 6 { 7 // 変換処理は割愛 8 } 9 10 // マーシャリング代わり 11 static ST_DATATYPE_REF^ CreateInstance(const ST_DATATYPE& src) 12 { 13 return gcnew ST_DATATYPE_REF(src.eDataType, src.sDataName); 14 } 15 E_DATATYPE eDataType; 16 System::String^ sDataName; 17 }; 18 19} 20ref class C_DATATYPE_LIST_WRAPPER 21{ 22public: 23 static DataManage::ST_DATATYPE_REF^ Get(int i) 24 { 25 return DataManage::ST_DATATYPE_REF::CreateInstance(C_DATATYPE_LIST[i]); 26 } 27}; 28 29... 30 31C_DATATYPE_LIST_WRAPPER::Get(0);

私は、データアクセスが多いorマーシャリングのコストが高い場合に上を、そうでない場合は下を採用することが多いです。
下はネイティブを完全に維持したままマネージからアクセスできるようになるので、出来れば下を優先したいなぁと。ネイティブの関連コードを完全に捨てるのであれば上ですけれども。

投稿2019/05/23 02:33

編集2019/05/24 03:43
moredeep

総合スコア1507

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

JanTh1989

2019/05/24 02:06 編集

ご回答ありがとうございます。 方法としては助言にもありましたが、ラッパークラスを採用することにしました。 ただ、疑問があります。 ラッパークラスのGet関数では、CreateInstance関数を使用して引数に配列要素値を入れた戻り値を、戻り値に設定する形にしています。 そして、戻り値型はST_DATATYPE^にしています。 ST_DATATYPEはref structにするということでしょうか? そうすると、C_DATATYPE_LISTの初期化子で発生するエラー「関数呼び出しの引数が多すぎます」が残ってしまいます。 ST_DATATYPE側はtypedef structの形態のままにして、戻り値型をST_DATATYPE。 戻り値をC_DATATYPE_LIST[i]にするとエラーが無くなりましたが、これだと何か不都合があるのでしょうか?
moredeep

2019/05/24 03:47

Nativeの構造体をManagedの構造体に変換しないといけないかなと思い、Get関数ではマーシャリングするようにしていました。 Managedの構造体を追加してCreateInstance関数(マーシャリング)を定義、使用するイメージでしたが、書いていないのにそんなことわかるはずないですよね。失礼いたしました。
JanTh1989

2019/05/24 04:19

構造体も含めて列挙体以外を完全にラップするということでしたか。 考えが及ばずすみません。 追加で頂いた情報も含め、対応方法の最終決定をしようと思います。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問