次の方法で共有

C++/CLI 2つのvalue struct間の相互参照問題の解決法

huahi11115 620 評価のポイント
2026-04-12T10:52:31.9666667+00:00

VB.netとC++/CLIを使用した開発です。

①Point3CLI0a ②MyPoint3a のvalue structを定義しています。 

①はC++/CLIとVB.netから頻繁に参照され、ファイルI/O処理で使用することから、高速化のためref classにできません。

②は①の上位クラスになり、これも高速化のためref classにできません。

現在、①を②の入力で使用する(逆もまた同じ)コンストラクターを作成していたところ、相互参照のためコンパイルエラーが出ました。この原因は、①から下方の②を参照していることだと分かるので、①ではプロトタイプ宣言をして③を記述しました。

ところがこの解決法は、従来ref classでは成功していましたが、value structではできないようなのです。

ここで解決法が分からず、詰まってしまいました。

③を記述する方法以外に、何か解決法はありますか。

C++/CLIコード


//①
//下位のクラス VB.netからも頻繁に参照される
public value struct Point3CLI0a {
public:
	float x, y, z;
	//ほかのメソッド類は掲載を省略
	Point3CLI0a::Point3CLI0a(MyPoint3 _p, UInt32 u1, float 倍率);//コンストラクター プロトタイプ宣言
};
//②
public value struct MyPoint3a {
	float x, y, z;
	//ほかのメソッド類は掲載を省略
	MyPoint3a(Point3CLI0a p0) { x = p0.x; y = p0.y; z = p0.z; }//コンストラクター
};
//③ ①のコンストラクターをここに書いた
Point3CLI0a::Point3CLI0a(MyPoint3 _p, UInt32 u1, float 倍率) {//コンストラクターの実体
	unsigned long* upx, * upy, * upz;
	upx = reinterpret_cast<unsigned long*>(&_p.x);//upxは_xへのポインターになっている
	*upx &= u1;//この操作で、_xが書き換わる
	upy = reinterpret_cast<unsigned long*>(&_p.y);
	*upy &= u1;
	upz = reinterpret_cast<unsigned long*>(&_p.z);
	*upz &= u1;
	x = _p.x * 倍率; y = _p.y * 倍率; z = _p.z * 倍率;
}

<モデレーター注>
この質問スレッドは、スパムフィルターの誤判定により削除されていましたがスレッドを復元させて頂きました。

開発者テクノロジ | C++
開発者テクノロジ | C++

C プログラミング言語の拡張機能として作成された高レベルの汎用プログラミング言語。低レベルのメモリ操作機能に加えて、オブジェクト指向、汎用、関数型の機能を備えています。


モデレーターによって推奨された回答

motosan 3,230 評価のポイント
2026-04-13T02:40:57.7+00:00

下記のように Point3CLI0a, MyPoint3a を前方参照すれば、ビルドできます。

  • Visual Studio 2026 18.4.3

修正)

  • ソースが壊れていたので修正しました。
  • またPoint3CLI0aの前方参照は不要なのでコメントにしました。
  • MyPoint3aの本体を外出しするのもやめました。
#include "pch.h"

using namespace System;

//value struct Point3CLI0a; // 不要
// C2061,C3417 error 対応
value struct MyPoint3a;

public value struct Point3CLI0a {
public:
    float x, y, z;
    // C2027 error 対応
    Point3CLI0a(MyPoint3a _p, UInt32 u1, float magnification);
};

public value struct MyPoint3a {
public:
    float x, y, z;
    // MyPoint3a(Point3CLI0a p0); 不要
    MyPoint3a(Point3CLI0a p0) { x = p0.x; y = p0.y; z = p0.z; }
};

// MyPoint3a::MyPoint3a(Point3CLI0a p0) { x = p0.x; y = p0.y; z = p0.z; } 不要
// C2027 error 対応
Point3CLI0a::Point3CLI0a(MyPoint3a _p, UInt32 u1, float magnification)
{
    unsigned long* upx, * upy, * upz;
    upx = reinterpret_cast<unsigned long*>(&_p.x);
    *upx &= u1;
    upy = reinterpret_cast<unsigned long*>(&_p.y);
    *upy &= u1;
    upz = reinterpret_cast<unsigned long*>(&_p.z);
    *upz &= u1;
    x = _p.x * magnification; y = _p.y * magnification; z = _p.z * magnification;
}

int main(array<System::String^>^ args)
{
    Point3CLI0a a1;
    a1.x = 1;
    a1.y = 2;
    a1.z = 3;
    MyPoint3a a2(a1);
    Console::WriteLine("a2 x = {0} y = {1}  z = {2}", a2.x, a2.y, a2.z);
    Point3CLI0a a1a(a2, 1u, 2.0);
    Console::WriteLine("a1a x = {0} y = {1}  z = {2}", a1a.x, a1a.y, a1a.z);
    return 0;
}

テスト結果です。(2行目は期待と違うようなので、デバッグで確認してください)

a2 x = 1 y = 2  z = 3
a1a x = 0 y = 0  z = 0

この回答は役に立ちましたか?

2 人がこの回答が役に立ったと思いました。

0 件の追加の回答

並べ替え方法: 最も役に立つ

お客様の回答

質問作成者は回答に "承認済み"、モデレーターは "おすすめ" とマークできます。これにより、ユーザーは作成者の問題が回答によって解決したことを把握できます。