簡體   English   中英

托管的C ++和C#

[英]managed C++ and C#

我在托管C ++中有一個類,該類的所有成員變量都在構造函數中初始化。 感興趣的成員是一個數組。 我從C#項目的.cs文件中調用它,將兩個項目與第一個項目的dll鏈接在一起。 但是,該函數表示一個或多個參數不正確,因此無法成功使用。

類聲明和函數聲明如下。 兩者都在.h文件中。

現在,我想按以下方式在.cs文件中調用該函數:

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

如果函數Config正確執行,它應該輸出0。但是,我得到一個負數,並且在使用供應商提供的表進行查找時,它指出一個或多個參數未正確設置。 我不知道如何克服這一點,因為我是托管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中傳遞的兩個nullptr有關,但是如果我將它們替換為參數AttrIdList和AttrValueList,則編譯器會出現錯誤:無法將參數3從'cli :: array ^'轉換為' NCTYPE_ATTRID_P'

順便說一句:NCTYPE_STATUS為無符號長,而NCTYPE_ATTRID_P為無符號長*。

無法將參數3從cli :: array ^轉換為NCTYPE_ATTRID_P
NCTYPE_ATTRID_P無符號長*

您不能將托管數組傳遞給純本機C ++函數,首先需要將其“轉換”為固定的無符號long *指針。

這是一種方法:

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

編輯:
請記住#include "windows.h"才能使用memcpy_s函數!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM