2

コンストラクター内で初期化されたすべてのメンバー変数を持つマネージC++のクラスがあります。対象のメンバーは配列です。2つのプロジェクトを最初のプロジェクトのdllにリンクして、C#プロジェクトの.csファイルから呼び出しています。ただし、この関数は、1つ以上のパラメーターが正しくないため、正常に使用できないことを示しています。

クラス宣言と関数宣言は次のとおりです。どちらも.hファイルにあります。

ここで、.csファイルの関数を次のように呼び出します。

var Driver = new Driver();
long status = Driver.Config2("CAN0", 8, Driver.AttrIdList, Driver.AttrValueList);
Console.WriteLine(status);

関数Configが正しく実行されると、0が出力されます。ただし、負の数を取得しており、ベンダーから提供されたテーブルでルックアップすると、1つ以上のパラメーターが正しく設定されていないことが示されます。私はマネージC++の初心者なので、この点を乗り越える方法がわかりません。すべての助けをいただければ幸いです。ありがとう。

コード宣言は次のとおりです。

public ref class Driver
    {
    public:

        NCTYPE_STATUS Status;
        NCTYPE_OBJH TxHandle;
        MY_NCTYPE_CAN_FRAME Transmit;
        array<NCTYPE_UINT32>^ AttrIdList;
        array<NCTYPE_UINT32>^ AttrValueList;
        array<char>^ Data;
        NCTYPE_UINT32 Baudrate;

    public:
        Driver()
        {
            Baudrate = 1000000;
            TxHandle = 0;
            AttrIdList =    gcnew array<NCTYPE_UINT32>(8);
            AttrValueList = gcnew array<NCTYPE_UINT32>(8);
            AttrIdList[0] =         NC_ATTR_BAUD_RATE;   
            AttrValueList[0] =      Baudrate;
            AttrIdList[1] =         NC_ATTR_START_ON_OPEN;
            AttrValueList[1] =      NC_TRUE;
            AttrIdList[2] =         NC_ATTR_READ_Q_LEN;
            AttrValueList[2] =      0;
            AttrIdList[3] =         NC_ATTR_WRITE_Q_LEN;
            AttrValueList[3] =      1;
            AttrIdList[4] =         NC_ATTR_CAN_COMP_STD;
            AttrValueList[4] =      0;
            AttrIdList[5] =         NC_ATTR_CAN_MASK_STD;
            AttrValueList[5] =      NC_CAN_MASK_STD_DONTCARE;
            AttrIdList[6] =         NC_ATTR_CAN_COMP_XTD;
            AttrValueList[6] =      0;
            AttrIdList[7] =         NC_ATTR_CAN_MASK_XTD;
            AttrValueList[7] =      NC_CAN_MASK_XTD_DONTCARE;

            interior_ptr<NCTYPE_UINT32> pstart (&AttrIdList[0]);
            interior_ptr<NCTYPE_UINT32> pend (&AttrIdList[7]);


            Data = gcnew array<char>(8);
            for (int i=0; i<8;i++)
                Data[i]=i*2;

        }

また、次のように宣言されているConfig関数のすぐ下に別のメソッドがあります。

NCTYPE_STATUS Config2 (String^ objName, int numAttrs, array<unsigned long>^ AttrIdList, array<unsigned long>^ AttrValueList )
    {
      msclr::interop::marshal_context^ context = gcnew msclr::interop::marshal_context();
      const char* name = context->marshal_as<const char*>(objName);


      char* name_unconst = const_cast<char*>(name);

      return ncConfig (name_unconst, 8, nullptr, nullptr);
      delete context;

    }

プログラムがコンパイルおよびビルドされます。これは実行時エラーです。関数Config2で渡された2つのnullptrと関係があると思いますが、これらをパラメーターAttrIdListおよびAttrValueListに置き換えると、コンパイラーはエラーを出します:パラメーター3を'cli ::array^'から'に変換できませんNCTYPE_ATTRID_P '

ところで:NCTYPE_STATUSはunsigned longですが、NCTYPE_ATTRID_Pはunsignedlong*です。

4

1 に答える 1

0

パラメータ3を'cli::array^'から'NCTYPE_ATTRID_P'に変換できません
NCTYPE_ATTRID_Pはunsignedlong*

管理対象配列を純粋なネイティブC++関数に渡すことはできません。最初に、固定のunsignedlong*ポインターに「変換」する必要があります。

これを行う方法は次のとおりです。

unsigned long* ManagedArrayToFixedPtr(array<unsigned long>^input)
{
    pin_ptr<unsigned long> pinned = &input[0];
    unsigned long* bufferPtr = pinned;

    unsigned long* output = new unsigned long[input->Length];
    memcpy_s(output, input->Length, bufferPtr,  input->Length);

    return output;
}

機能のテスト:

array<unsigned long>^ larray = gcnew array<unsigned long> {2,4,6,8,10,12,14,16};
unsigned long* lptr = ManagedArrayToFixedPtr(larray); //returns pointer to 2

編集:
memcpy_s#include "windows.h"関数を使用できるようにするためのRememer!

于 2012-08-05T15:53:43.040 に答える