![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
現在、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);
よろしくお願いします。
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_08.png?5a7ff87)
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で質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) エクセルVBAで教えて頂きたいのですが? 2 2022/12/31 20:28
- Visual Basic(VBA) セルS2に入力した「月」と一致したB列の右隣へセルS110の値を転記する下記マクロを実行するとエラー 2 2022/12/06 17:32
- Visual Basic(VBA) ①ExcelVBAでカレンダーを作り、別のユザーフォームで日付を入力したいのですがエラーになります。 1 2023/02/17 18:39
- Visual Basic(VBA) 別シートのデータを参照して値を入れたい。 まとめデータシートのC列D列の値を商品一覧シートのコードが 7 2022/08/17 13:20
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- Visual Basic(VBA) 形式を選択して貼り付け 以下のコードで「元」シートと「先」シートのA列に同じ値があったら指定範囲をコ 5 2022/11/11 07:30
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- Excel(エクセル) エクセルのマクロについて教えてください。 2 2023/01/11 08:33
- その他(プログラミング・Web制作) pythonでクラスで複数のメソッドを利用する方法 2 2022/04/15 04:17
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
レコード件数の表示
-
abstract と static を一緒に付...
-
Java初級 引数に適用できません
-
Google Apps Script で getRang...
-
なぜprotected overrideなのか
-
メソッドの引数に指定されてい...
-
C# 点の描き方をおしえてくだ...
-
不要なstaticメソッドの見分け...
-
String.containsの反対機能はあ...
-
javaに"search"という関数 or ...
-
【アクセス修飾子】アクセス修...
-
JavaでOpenCVを扱いたいのです...
-
C# asp.net HTMLタグのエスケ...
-
Javaの問題なんですが、Window ...
-
クラスを作るとメソッドの数が...
-
C言語での文字列より値を抜き出す
-
YYYYMMDD書式の日付に対する適...
-
継承とオーバーライド
-
VB FindFirstの動きを.Netで・・・
-
JavaからCへ
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
レコード件数の表示
-
Java初級 引数に適用できません
-
String.containsの反対機能はあ...
-
public static void main (Stri...
-
abstract と static を一緒に付...
-
Google Apps Script で getRang...
-
StringBufferからStringへキャ...
-
メソッド宣言の戻り値の型にク...
-
javaに"search"という関数 or ...
-
C# 点の描き方をおしえてくだ...
-
Java初心者です、エラーの意味...
-
なぜprotected overrideなのか
-
親の親のメソッドを呼ぶには?
-
C# でメソッドに送られてきたOb...
-
Javaの関数名が長い?
-
別クラスのmainメソッドの実行
-
[クラス名].[メソッド名].[メソ...
-
コマンドライン引数のチェック
-
contextってなんですか?
-
説明文書でのメソッド・変数の...
おすすめ情報