C++/CLI でSystem::Array関連のコンパイルが通りません。

huahi11115 355 評価のポイント
2024-12-03T06:20:25.3366667+00:00

名称未設定-1

C++/CLIで作成したDLLをVB.netで運用しています。

VB.netで定義した配列の要素数をC++/CLI側で変更します。

s.test3(ar1) で、single配列の要素数を変更する動作は正常です。

これを発展させて、配列の要素型が何であっても処理できるメソッドを作りたいです。

要素型をintとfloatで実験したのですが、

Array<int>とArray<float>の親クラスはいずれもSystem::Arrayなので、void test1(System::Array ^% a1) と受けているのですが、Array::Resize(a1, 4);でコンパイルが通りません。

System::Array型のオブジェクトなのにResizeが使えないのはなぜですか。

配列の要素の型に関係なくArray::Resizeを行いたいので、解決方法を教えて下さい。

<VB.net>

  Dim s As New TestClass

  'Dim ar1(9) As Integer ’integer,single どちらも使いたい

  Dim ar1(9) As Single

  '正常に動作する

  Debug.Print($"** {ar1.Count}") '10が表示される

  s.test3(ar1)'C++/CLIで配列のresizeを行う

  Debug.Print($"** {ar1.Count}") '2が表示される

<C++/CLI>

public ref class TestClass {

//a1にはint、float どちらも入力したい

void test1(System::Array ^% a1) {

//関数テンプレート"Syste::Array::resize" のインスタンスが引数リストと一致しません。

//Array::Resize(a1, 4);  コンパイルが通らない

}

void test3(array<float>^% a1) {//正常に動作する array<float>^%で受けているので当然だと思います。

Array::Resize(a1, 2);

}

};

.NET
.NET
.NET ソフトウェア フレームワークに基づく Microsoft テクノロジ。
74 件の質問
C++
C++
C プログラミング言語の拡張機能として作成された高レベルの汎用プログラミング言語。低レベルのメモリ操作機能に加えて、オブジェクト指向、汎用、関数型の機能を備えています。
25 件の質問
0 件のコメント コメントはありません
{count} 件の投票

承認済みの回答
  1. gekka 10,646 評価のポイント MVP
    2024-12-03T09:19:18.8133333+00:00

    System::Array::Resizeはジェネリック関数です。

    public:
    generic <typename T>
     static void Resize(cli::array <T> ^ % array, int newSize);
    

    ジェネリック型が省略された場合、型推論できれば省略可能ですが、推論できなければコンパイルは通りません

    System::Array^からSystem::Array<T>をコンパイル時に推測することは不可能なので、当然エラーになります。

    無理やりでもやりたいなら、実行時に型をリフレクションで解析してやる必要があります。

    #include "pch.h"
    #include <iostream>
    
    using namespace System;
    
    public ref class TestClass {
    public:
    
    
        void test1(System::Array^% a1) {
    
            //Array::Resize(a1, 4); //第1引数の型推論ができないのでコンパイルが通らない
    
            //リフレクションでarrayの元の型を取得して
            //その型のジェネリック関数を取得する
            System::Type^ t = a1->GetType();
            System::Type^ tArray = System::Array::typeid;
            System::Type^ tElement = t->GetElementType();
            System::Reflection::MethodInfo^ miResizeT = tArray->GetMethod(L"Resize")->MakeGenericMethod(tElement);
    
            // ジェネリック関数をリフレクションから実行
            array<System::Object^>^ param = { a1 , 1 };
            miResizeT->Invoke(NULL, param); //static関数なので第一引数はナシ
            a1 = dynamic_cast<System::Array^>(param[0]); //参照が変更されているの戻す
        }
    
        generic <class T>
        void test2(array<T>^% a)
        {
            Array::Resize<T>(a, 2);
        }
    
        void test3(array<float>^% a1) {
    
            Array::Resize(a1, 3); //ジェネリック型が型推論で省略できているだけ
            Array::Resize<float>(a1, 3); //本来のジェネリック関数の呼び出し
        }
    
    };
    
    int main(array<System::String^>^ args)
    {
        TestClass^ c1 = gcnew TestClass();
        auto af = gcnew array<float, 1>(10);
        System::Array^ a = af;
        c1->test1(a); Console::Out->WriteLine(a->Length);
        c1->test2(af); Console::Out->WriteLine(af->Length);
        c1->test3(af); Console::Out->WriteLine(af->Length);
    
    }
    
    1 人がこの回答が役に立ったと思いました。

0 件の追加の回答

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

お客様の回答

回答は、質問作成者が [承諾された回答] としてマークできます。これは、ユーザーが回答が作成者の問題を解決したことを知るのに役立ちます。