- ベストアンサー
C#とC++/CLI間でポインタが指す内容が変わる
- C#とC++/CLI間のクラスのやり取りで、ポインタが指す内容が変化する問題について
- C++/CLI側で定義されているクラスとメソッドの使い方について紹介します
- C#側でのメソッド参照時に注意すべき点について解説します
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
// C++/CLI側。 #include <cstdio> #include <windows.h> using namespace System; namespace CppNative { struct SomeHeaderInfo { // なんで要素数が 2 なのか、この構造体で何がしたいのか、まったくもって不明。 char Type[2]; char MessageLength[2]; }; inline ULONG OpenDummySession(ULONG code, const SomeHeaderInfo& info) { for (int i = 0; i < 2; i++) printf(__FUNCTION__ "(): Type[%d] = %d, MessageLength[%d] = %d\n", i, static_cast<int>(info.Type[i]), i, static_cast<int>(info.MessageLength[i])); return code; } } namespace CppManaged { public value class SomeHeaderInfo { public: char Type0; char Type1; char MessageLength0; char MessageLength1; }; public value class DataPack { public: UInt32 Code; SomeHeaderInfo Header; }; public ref class Session { public: static UInt32 Open(DataPack% dataPack) { CppNative::SomeHeaderInfo temp = {}; temp.Type[0] = dataPack.Header.Type0; temp.Type[1] = dataPack.Header.Type1; temp.MessageLength[0] = dataPack.Header.MessageLength0; temp.MessageLength[1] = dataPack.Header.MessageLength1; return CppNative::OpenDummySession(dataPack.Code, temp); } }; } // C#側。 { CppManaged.DataPack dataPack = new CppManaged.DataPack(); dataPack.Code = 128; dataPack.Header.Type0 = 10; dataPack.Header.Type1 = 20; dataPack.Header.MessageLength0 = 110; dataPack.Header.MessageLength1 = 120; uint status = CppManaged.Session.Open(ref dataPack); Console.WriteLine("Status = {0}", status); } C++/CLIは玄人向けの言語です。 悪いことは言わないので、怪我する前にネイティブC++とC#を基礎から勉強し直した方がいいです。
その他の回答 (1)
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
異なる言語間では「引数の参照渡し」は出来ません。 参照する場所では「参照した先」が「別世界」なので、参照する時点では「参照すべき場所に、参照すべき内容のデータが存在しない」のです。 「参照渡し」と「ポインタ渡し」は、言語仕様上、ほぼ同じ動作を行いますから、混同している人が多いですが「実装レベルでは、まったく異なる記述」なので注意しましょう。 また「異なる言語での引数渡し」ですので、関数を参照している場所と、関数を定義している場所で「関数の呼び出し規約」も統一させなければなりません。 「関数の呼び出し規約」とは、例えば __stdcallとか__cdeclとかってマクロで定義してあるヤツです。 これが一致してないと、引数の積み込みと取り出しの実装が食い違ったり、引数をレジスタ渡ししているのにスタックから取り出そうとしたりと、色々と問題が起きます。
お礼
ご回答ありがとうございます。 異なる言語間で引数を渡すのは難しそうですね。 実際、値を受けわたす方法としては、「参照渡し」や「ポインタ渡し」などを使わずに、変数を一つ一つ渡す方がよいのでしょうか? 載せたコードでは省略しましたが、かなり量が多くて・・・。
お礼
ご回答ありがとうございます。 すでに深手を負ってる感は否めないですねw。 ご指摘通り、基礎をもっと勉強します。。 もし、public value class DataPackにポインタ変数が含まれていた場合、C#側で正しい値を取得する方法はあるのでしょうか? C#側でポインタを使うべきでないとは思うのですが、利用しなければいけないソフトが処理の結果をポインタで返して来るもので。