2012-07-18 131 views
2

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

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

,我想調用該函數在.cs文件如下:

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

如果功能配置正確執行,應該輸出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'

BTW:NCTYPE_STATUS爲無符號長整型,而NCTYPE_ATTRID_P爲無符號長整型*。

+0

請提供所有適用的代碼,例如什麼是類型NCTYPE_STRING和NCTYPE_UINT32 – 2012-07-18 20:35:41

+0

NCTYPE_UINT32是無符號長整型,而NCTYPE_STRING是char *。所有這些都是在供應商的庫中聲明的,並且包含太長的時間。 – Nathan822 2012-07-18 20:39:49

+0

CLR中的無符號長整型爲32位 – Nathan822 2012-07-18 20:42:58

回答

0

cannot convert parameter 3 from 'cli::array^' to 'NCTYPE_ATTRID_P'
NCTYPE_ATTRID_P is unsigned long*

可以託管數組不傳遞到一個純粹的本地C++的功能,首先需要「轉換」到一個固定的無符號長*指針。

這裏有一個辦法做到這一點:

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 

編輯:
Rememer到#include "windows.h"能夠使用memcpy_s功能!