
現在、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);
よろしくお願いします。

No.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#を基礎から勉強し直した方がいいです。
ご回答ありがとうございます。
すでに深手を負ってる感は否めないですねw。
ご指摘通り、基礎をもっと勉強します。。
もし、public value class DataPackにポインタ変数が含まれていた場合、C#側で正しい値を取得する方法はあるのでしょうか?
C#側でポインタを使うべきでないとは思うのですが、利用しなければいけないソフトが処理の結果をポインタで返して来るもので。
No.1
- 回答日時:
異なる言語間では「引数の参照渡し」は出来ません。
参照する場所では「参照した先」が「別世界」なので、参照する時点では「参照すべき場所に、参照すべき内容のデータが存在しない」のです。
「参照渡し」と「ポインタ渡し」は、言語仕様上、ほぼ同じ動作を行いますから、混同している人が多いですが「実装レベルでは、まったく異なる記述」なので注意しましょう。
また「異なる言語での引数渡し」ですので、関数を参照している場所と、関数を定義している場所で「関数の呼び出し規約」も統一させなければなりません。
「関数の呼び出し規約」とは、例えば __stdcallとか__cdeclとかってマクロで定義してあるヤツです。
これが一致してないと、引数の積み込みと取り出しの実装が食い違ったり、引数をレジスタ渡ししているのにスタックから取り出そうとしたりと、色々と問題が起きます。
ご回答ありがとうございます。
異なる言語間で引数を渡すのは難しそうですね。
実際、値を受けわたす方法としては、「参照渡し」や「ポインタ渡し」などを使わずに、変数を一つ一つ渡す方がよいのでしょうか?
載せたコードでは省略しましたが、かなり量が多くて・・・。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
レコード件数の表示
-
Fileの読み取り専用の解除
-
Java初級 引数に適用できません
-
StringBufferからStringへキャ...
-
説明文書でのメソッド・変数の...
-
String.containsの反対機能はあ...
-
Java初心者です、エラーの意味...
-
staticのメリット、デメリット
-
Google Apps Script で getRang...
-
JDBC Connectionを開放し続ける...
-
contextってなんですか?
-
javaに"search"という関数 or ...
-
エクセルVBAで、条件に一致する...
-
「タイプ初期化子が例外をスロ...
-
オブジェクト参照がオブジェク...
-
変数名の付け方
-
複数のクラスで共通した関数を...
-
c++,ある関数のクラスから別の...
-
JSPで<SELECT>の中にDBから持っ...
-
EXCEL VBAにて動的にCheckBOXを...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
レコード件数の表示
-
Java初級 引数に適用できません
-
String.containsの反対機能はあ...
-
別クラスのmainメソッドの実行
-
abstract と static を一緒に付...
-
StringBufferからStringへキャ...
-
説明文書でのメソッド・変数の...
-
Java初心者です、エラーの意味...
-
YYYYMMDD書式の日付に対する適...
-
コマンドライン引数のチェック
-
Google Apps Script で getRang...
-
staticのメリット、デメリット
-
メソッドの引数に指定されてい...
-
スーパークラスからサブクラス...
-
return new使用時
-
メソッド宣言の戻り値の型にク...
-
インターフェースについて
-
CSVから読み込んだデータの保持...
-
問題の意味が分かりません
-
JavaからCへ
おすすめ情報