C++/C#間での構造体の引き渡し方法に関するコンパイルエラーの原因

このQ&Aのポイント
  • C++とC#で構造体を定義して引き渡ししようとした際に、「Msg*から_Msg*に変換できません」というコンパイルエラーが発生してしまう。構造体の定義は同じなので、原因は何か。
  • C++で定義した構造体をC#から呼び出そうとしているが、「Msg*から_Msg*に変換できません」というコンパイルエラーが出る。
  • C++とC#で同じ構造体を定義して引き渡ししようとしたが、「Msg*から_Msg*に変換できません」というコンパイルエラーが発生してしまう。原因は何か。
回答を見る
  • ベストアンサー

C++/C#間での構造体の引き渡し方法に関して

現在、C++で作成したクラスを、 C#から呼び出し実行しようとしております。 引数として、構造体を利用したいので、 C++側、C#側でそれぞれ下記のように 構造体を定義しました。 【C++】 typedef struct _Msg { ULONG Code; ULONG sessionId; }Msg; 【C#】 [StructLayout(LayoutKind.Sequential)] public struct Msg { public uint Code; public uint sessionId; } そして、下記のようにC++側で定義したクラスを C#側で呼び出そうとしたのですが、 「Msg*から_Msg*に変換できません」という コンパイルエラーが発生してしまいました。 構造体の定義は同じものになっていると思うのですが、 この原因は何だと考えられるでしょうか。 よろしくお願いいたします。 【C++】 ULONG Wrap::API( Msg* sample_Msg ) { return 1; } 【C#】 Msg sample_msg; Wrap.API(&sample_msg);

質問者が選んだベストアンサー

  • ベストアンサー
  • sygh
  • ベストアンサー率76% (42/55)
回答No.2

// C++/CLI側の例。 namespace CppCliString { // マネージ構造体(値クラス)。 public value class MessagePack { public: UInt32 Code; UInt32 SessionId; }; public ref class Class1 { public: static void PrintAndClear(MessagePack% msg) { printf(__FUNCTION__ "(): Code = 0x%08X, SessionID = %u\n", msg.Code, msg.SessionId); msg.Code = 0xFFFFFFFF; msg.SessionId = 0; } }; } // C#側の例。 { CppCliString.MessagePack msg = new CppCliString.MessagePack(); msg.Code = 10; msg.SessionId = 7; Console.WriteLine("Code = 0x{0}, SessionID = {1}", msg.Code.ToString("X8"), msg.SessionId); CppCliString.Class1.PrintAndClear(ref msg); Console.WriteLine("Code = 0x{0}, SessionID = {1}", msg.Code.ToString("X8"), msg.SessionId); } C#側に合わせたデータ型定義をC++/CLI側で行なうのが基本です。 C#側にポインタ型のインターフェイスを見せるようなことは、何がなんでも避けるべきです。 というか質問を見る限り、明らかにネイティブC++とC++/CLIを混同している上に、C#でポインタを使うことがいかに非生産的な行為であるかを認識されていないようなので、C#とネイティブC++を一通り学び終えた後で、下記の書籍を熟読してからC++/CLIに手を付けることをお勧めします。 http://www.amazon.co.jp/%E5%AE%9F%E8%B7%B5C-CLI-%E6%A5%B5%E3%82%81%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E5%9F%BA%E7%A4%8E%E3%81%A8%E5%AE%9F%E7%94%A8%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-%E4%B8%AD-%E5%8D%9A%E4%BF%8A/dp/4797336277

kokukuma
質問者

お礼

丁寧なご回答ありがとうございます。 おかげさまで、やりたいことを実行できました。 ご指摘通り、もうすこしC++/CLIについて勉強したいと思います。 ありがとうございました。

その他の回答 (1)

回答No.1

C++のstructとC#のstructはまったくの別物てことをふまえての質問でしょうか?

関連するQ&A

  • C#で構造体の配列を持った構造体を使いたいのですが

    C#で構造体の配列を持った構造体を使いたいのですが Cならば struct xyz { struct abc _abc[32]; int index; }; struct abc { int a; int b; int c; }; struct xyz _xyz[8]; xyz[0]._abc[3].b = 1; のような使い方で という感じで やっていた事を C#で 同じような事をやろうとしても うまくいきません うまくやる方法をどなたかご存知ないでしょうか Visual Studio 2005行った場合 コンパイルで 構文エラーです。不適切な配列の宣言子です。マネージ配列を宣言するには、次元指定子を変数の識別子の前に指定します。固定サイズ バッファ フィールドを宣言するには、フィールド型の前に fixed キーワードを使用します となり fixed をつけると 固定サイズ バッファの型は次のうちの 1 つでなければなりません: bool、byte、short、int、long、char、sbyte、ushort、uint、ulong、float または double となってしまいます

  • 配列を含んだ構造体への値設定について教えて下さい。

    配列を含んだ構造体への値設定について教えて下さい。 下記のような構造体の定義があります。 typedef struct A_T { UINT64 a1; UINT32 a2; } A_t; typedef struct B_T { UINT32 b1; A_t b[8]; } B_t; 構造体B_tを関数の引数で渡し、A_tのa1とa2に値を設定したいのですが、プログラミング初心者の為、どのように作ればよいのかわかりません。 どうぞ教えて下さい。

  • C#とC++/CLI間でポインタが指す内容が変わる

    現在、C++/CLIプログラムをC#で使う必要があり、 C++/CLIで定義したメソッドとクラスでC#側とやり取りする必要が生じております。 以下の書き方で、C++/CLIとC#間のクラスのやり取りはできたのですが、 C++/CLI側で定義されているメソッド内で、ポインタが指し示す値(*id.head)が変わってしまいます(文字化けみたいな感じになる)。 引き渡したポインタ変数の値は一致しているのですが、 どうすれば、C++/CLI側で値を正しく取得できるのでしょうか?。 【C++/CLI側で定義されているクラス】 public value class class1 { public : ULONG code; header    *head; }; typedef struct _header { CHAR achCHdrType[2]; CHAR achMsgLen[2]; } header ; 【C++/CLI側で定義されているメソッド】 ULONG session::open(class1& id) { return session_oepn(id.code, *id.head) } 【C#側でのメソッド参照】 class1 c1 = new class1(); uint status = session.open(&c1); よろしくお願いします。

  • C++/CLIのDLLを、C#で参照した際の変数型

    現在、C++/CLIで作成したDLLを、C#で使おうとしています。 http://xptn.dtiblog.com/blog-entry-20.html 上記サイトを参考に、DLLを参照することはできたのですが、 C++/CLI側で「ulong」で定義した引数が、 C#で参照したとき「uint」に変わってしまっています。 【C++/CLI】  opensession(ULONG arg1, ULONG* arg2 ); 【C#】  opensession(UINT arg1, UINT* arg2); 調べてはいるのですが、 この原因がどうしてもわかりません。 ご教授のほど、よろしくお願いします。

  • 構造体を型の異なる構造体に代入

    C言語初心者です。 今回の質問は入力された構造体のメンバのデータを型の異なる構造体に代入したいのですが、毎回コンパイラにおこられてしまいます(汗)具体的には typedef struct MSG{ longint type; int flg; int Dt[64]; }t_msg; このDt[64]を以下の構造体に代入します。 typedef struct SC_MSG{ char a; char b; short c; char d; char e; short f; }t_sc_msg; その際、異なる関数で処理するため、 main(){ foo(&t_msg); }; void foo(t_msg *pt_msgdt){ t_sc_msg = (*pt_msgdt+8); ココがエラーになってしまいます。 何か、根本的な間違いをおかしている気がします。 ご指導の方、宜しくお願いします。 ちなみにOSはLinuxでコンパイラーはgccです。

  • Golang/cgo GoからCへの構造体実体渡し

    Windows用のとあるDLLがあり、Goから呼び出そうとしています。DLL内のAPIに、構造体の実体を受け取る引数があるのですが、Goからはどのように呼び出せば良いですか? (DLLライブラリ側の例) typedef struct { uint32_t id; uint16_t age; char name[20]; } Person; bool AddPerson(Person p); (Go側の実装(エラー処理省略)) type Person struct { id uint32 age uint16 name [20]byte } dll, err := syscall.LoadDLL("とあるDLL") proc, err := dll.FindProc("AddPerson") p1 := Person{id:1, age:18} copy(p1.name[:], []byte("taro")) proc.Call( p1を渡したい、ここに何と書くべき? ) 以上、よろしくお願いします。

  • 構造体の初期化の時にポインタを入れるにはどうしたらいいですか?

    構造体の初期化の時にポインタを入れるにはどうしたらいいですか? 例えば、このような構造体で↓ struct PACKET { uint16_t size; // データの長さ uint16_t *data; // データバイト列 }; 初期化の時にsizeとdataを入れるにはどうしたらいいのでしょうか? dataがuint16_t*じゃなくてchar*なら struct PACKET { uint16_t size; // データの長さ char *data; // データバイト列 }; struct PACKET p = { 5, "12345" }; というようにできるのですが・・・

  • OVERLAPPED構造体が分かりません・・。

    シリアルポートで非同期データ通信するプログラム作成初歩段階です。 ReadFileの第5引数にはOVERLAPPED構造体へのポインタを指定することは分かったのですが。この構造体の各メンバにどんな値を入れたらいいのか分りません・・・。 よろしくお願いします。 typedef struct _OVERLAPPED { ULONG_PTR Internal; ULONG_PTR InternalHigh; DWORD Offset; DWORD OffsetHigh; HANDLE hEvent; } OVERLAPPED;

  • 条件によって構造体のリスト構造を変えたい

    こんにちは。 C(C++)で構造体を使っているのですが、まだまだ未熟で使い方が良く分かりません。以下のことを実施したいのですが、やり方をどなたかご教授頂けませんでしょうか。よろしくお願いします。 条件によって構造体のリスト構造を変えたいのです。 例えば、 条件1の場合は 構造体a→構造体b 条件2の場合は、 構造体a→構造体c 上記のようにです。そして構造体のルートから参照先をたどっていくことで、配下の構造体の値を取得したいのです。 文法上許されないようですが、イメージとしては、 struct a aa; aa.c->b.aa ということをしたいのです。よろしくお願いします。 struct a{ char a; char b; struct c; : }; struct b{ char aa; : }; struct c{ : : };

  • C言語の構造体についてなんですが。

    struct LIST {     struct Num* number;     struct LIST* next;/* 次の要素へのポインタ */ }*root; struct Num{     int a;     struct Num* next; /* 次の要素へのポインタ */ }*numroot; と構造体を定義したときに、 main(){     struct LIST *p;     for(p = root; p != NULL; p = p->next) ; } とすれば、pの先頭からNULLまでを参照していくことは分かるんですが、pのnumberの先頭からNULLまでの参照方法(プログラムのfor文の記述方法)がイマイチわかりません。つまり、構造体の構造体をどのように参照するかということです。 これを実現したい理由は、構造体内での数の格納を配列(固定長)ではなく可変長で格納したいからです。 分かる方は解答をお願いします。

専門家に質問してみよう