C++/cli:无法转换参数 1

Posted

技术标签:

【中文标题】C++/cli:无法转换参数 1【英文标题】:C++/cli: Cannot convert parameter 1 【发布时间】:2013-05-11 19:25:34 【问题描述】:

我正在尝试将与 DLL 一起使用的 C# 代码转换为 C++,以便我的 c++ 应用程序可以与 DLL 一起使用。所以在这里我正在开发一个 C++/cli 应用程序

我正在编写这个 C# 代码:

private void SendUSBData(byte[] Data)

    if (this.USB.SpecifiedDevice != null)
    
        this.USB.SpecifiedDevice.SendData(Data);
    

SendData() 是 dll 中可用的方法。以下是它在dll中的定义

public void SendData(byte[] data);

好的,现在在我的 C++ 代码中,我尝试像这样转换 C# 代码

void MissileLauncher::sendUSBData(unsigned char *data)

    if(usb.SpecifiedDevice!=nullptr)
    
        //System::Byte
        usb.SpecifiedDevice->SendData(&data);
    

运行此代码时出现以下错误

1>------ Build started: Project: CallToCSharp, Configuration: Debug Win32 ------
1>  MissileLauncher.cpp
1>MissileLauncher.cpp(200): error C2664: 'UsbLibrary::SpecifiedDevice::SendData' : cannot convert parameter 1 from 'unsigned char **' to 'cli::array<Type,dimension> ^'
1>          with
1>          [
1>              Type=unsigned char,
1>              dimension=1
1>          ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

我也尝试了以下方法

void MissileLauncher::sendUSBData(array<System::Byte>^data)

    if(usb.SpecifiedDevice!=nullptr)
    
        //System::Byte
        usb.SpecifiedDevice->SendData(&data);
    

它给了我以下错误

1>------ Build started: Project: CallToCSharp, Configuration: Debug Win32 ------
1>  MissileLauncher.cpp
1>MissileLauncher.cpp(125): error C2664: 'MissileLauncher::sendUSBData' : cannot convert parameter 1 from 'unsigned char *' to 'cli::array<Type> ^'
1>          with
1>          [
1>              Type=unsigned char
1>          ]
1>MissileLauncher.cpp(159): error C2664: 'MissileLauncher::sendUSBData' : cannot convert parameter 1 from 'unsigned char *' to 'cli::array<Type> ^'
1>          with
1>          [
1>              Type=unsigned char
1>          ]
1>MissileLauncher.cpp(164): error C2664: 'MissileLauncher::sendUSBData' : cannot convert parameter 1 from 'unsigned char *' to 'cli::array<Type> ^'
1>          with
1>          [
1>              Type=unsigned char
1>          ]
1>MissileLauncher.cpp(166): error C2664: 'MissileLauncher::sendUSBData' : cannot convert parameter 1 from 'unsigned char *' to 'cli::array<Type> ^'
1>          with
1>          [
1>              Type=unsigned char
1>          ]
1>MissileLauncher.cpp(186): error C2664: 'MissileLauncher::sendUSBData' : cannot convert parameter 1 from 'unsigned char *' to 'cli::array<Type> ^'
1>          with
1>          [
1>              Type=unsigned char
1>          ]
1>MissileLauncher.cpp(188): error C2664: 'MissileLauncher::sendUSBData' : cannot convert parameter 1 from 'unsigned char *' to 'cli::array<Type> ^'
1>          with
1>          [
1>              Type=unsigned char
1>          ]
1>MissileLauncher.cpp(200): error C2664: 'UsbLibrary::SpecifiedDevice::SendData' : cannot convert parameter 1 from 'cli::array<Type> ^*' to 'cli::array<Type> ^'
1>          with
1>          [
1>              Type=unsigned char
1>          ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

我怎样才能摆脱这个?

更新

按照答案中的建议,我尝试了以下代码

void MissileLauncher::sendUSBData(unsigned char *data)

    if(usb.SpecifiedDevice!=nullptr)
    
        int N = 10;
            cli::array<char>^ newData = gcnew cli::array<char>(N);

        for (int i = 0; i < N; ++i)
            newData[i] = data[i];

        //System::Byte
        usb.SpecifiedDevice->SendData(newData);
    

现在,它给了我以下错误

1>------ Build started: Project: CallToCSharp, Configuration: Debug Win32 ------
1>  MissileLauncher.cpp
1>MissileLauncher.cpp(206): error C2664: 'UsbLibrary::SpecifiedDevice::SendData' : cannot convert parameter 1 from 'cli::array<Type> ^' to 'cli::array<Type,dimension> ^'
1>          with
1>          [
1>              Type=char
1>          ]
1>          and
1>          [
1>              Type=unsigned char,
1>              dimension=1
1>          ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

说实话,我真的不知道我是否按照建议正确编码了这段代码。

【问题讨论】:

不打算开始编辑大战,但没有理由将标签添加回标题。无需复制您已有的。 【参考方案1】:

您需要将数据从char* 转换为cli::array&lt;char&gt;^cli::array 模板是在 C++/CLI 中实现 System::Array 的模板。为此,您需要知道数据的长度:

int N = /* length of data */
cli::array<System::Byte>^ newData = gcnew cli::array<System::Byte>(N);
for (int i = 0; i < N; ++i)
    newData[i] = data[i];

【讨论】:

非常感谢您的回复。我想这是应该在方法内部的代码。那么,请问您指的是哪种方法?在我的 c++ 代码中,我展示了 2 种不同的尝试,使用 2 种不同的方法样式,这就是为什么 在哪里转换为cli::array 并不重要,重要的是您遵循UsbLibrary::SpecifiedDevice::SendData 的界面。此函数需要一个cli::array&lt;char&gt;^ 参数,因此您需要将转换后的数据作为其参数传递。 请看一下编辑后的代码。如果我做错了什么,请纠正我。 我的错,我的原始代码有错误。您需要使用System::Byte/unsigned char 类型的cli::array。以前是 char 映射到 System.SByte .NET 类型。我已经更新了我的答案。 你能帮我看看吗***.com/questions/16580018/…【参考方案2】:

您的第二个版本几乎是正确的。这是来自问题:

void MissileLauncher::sendUSBData(array<System::Byte>^data)

    if(usb.SpecifiedDevice!=nullptr)
    
        //System::Byte
        usb.SpecifiedDevice->SendData(&data);
    

这是解决方法:

        usb.SpecifiedDevice->SendData(/* & <- take that out */ data);

【讨论】:

@Knight:你有没有像我的回答说的那样去掉&amp;?哎呀,我复制了你的第一个版本而不是你的第二个版本。我正在修复您的第二个版本。【参考方案3】:

使用以下代码,将 c 风格的字节数组转换为 CLR 字节数组:

using namespace System::Runtime::InteropServices;

const char* from = xxxx; //(or unsigned char/signed char)
size_t length = strlen(from); 
array<System::Byte>^ target = gcnew array<unsigned char>(length);
Marshal::Copy((System::IntPtr)from, target, 0, length);

【讨论】:

以上是关于C++/cli:无法转换参数 1的主要内容,如果未能解决你的问题,请参考以下文章

C++/CLI 为啥对托管不可见

VS 2012项目转换烦恼

C++/CLI 管理的 VS。非托管空头

在 C++/CLI 中,如何声明和调用带有“out”参数的函数?

转换为C ++ CLI托管对象引用的本机指针?

如何使用 C++/CLI Wrapper 将变量参数从托管传递到非托管?