将 const std::vector<char> 转换为 unsigned char*?
Cast const std::vector<char> to unsigned char*?
为 C 库编写 C++ 包装器。在库中有一个函数接受缓冲区作为 unsigned char *
。由于使用 C++,我将我的真实缓冲区存储在 std::vector<char>
中,此外,在包装器 class 中,我还添加了 const
,因为有问题的缓冲区是一个输入缓冲区,它不会被修改。但是我的代码没有编译,demo:
#include <stdio.h>
#include <vector>
void x(unsigned char *s)
{
printf("%s\n", s);
}
int main()
{
const std::vector<char> s(10);
x(reinterpret_cast<unsigned char *>(s.data())); // FAILS
}
id有什么问题?如果我从 const std::vector<char> s(10);
中删除 consts
它会起作用,但我更喜欢那样。
您的错误是因为您将 std::vector
声明为 const
。
如果你去掉常量,它就可以正常工作。 (如所见here)
无论如何,您应该问问自己是否真的需要在数组中存储 char
或 unsigned char
。
如果您想保留 const
,则必须使用 const_cast
,但您的行会变得很长:
x(const_cast<unsigned char*>(reinterpret_cast<const unsigned char *>(s.data())));
如果您有权访问该库,最好将缓冲区标记为 const
(如果它未更改)。
但是,由于它不是 const
,您不能确定它不会被函数修饰,因此,您不应该将 std::vector
保留为 const
.
您必须执行 const_cast
删除常量,然后 reinterpret_cast
将 char *
转换为 unsigned char *
试试这个:x(reinterpret_cast<unsigned char*>(const_cast<char *>(s.data())));
注意:但也请记住 const_cast
只有在转换最初是非常量的变量时才是安全的。请参阅 this 答案。
这就是我在跨平台实施过程中解决同样问题的方法。上述方法在 Windows 和 Linux (Redhat) 上运行良好,但在 Solaris 10 和 IBM AIX 7 上运行不佳。
Solaris 10 使用上述建议的方法给出以下错误。
'nofieldident: data is not a member of const std::vector<unsigned char>'
这是一种处理矢量数据 'const'
ness 的方法,它适用于 Windows、Linux、Solaris
#include <iostream>
#include <vector>
using namespace std;
/// Data Interface, which is visible to the outside
class IDataInterface {
public:
// Get the underlying data as a const data pointer
virtual const unsigned char* Data(size_t& nSize) = 0;
};
/// Implemetation of the IDataInterface
class CData : public IDataInterface {
public:
// Constructor
CData(vector<unsigned char> data);
// Overriden function of the interface
const unsigned char* Data(size_t& nSize);
private:
/// Actual data member
vector<unsigned char> m_vData;
};
/// Constructor implementation
CData::CData(vector<unsigned char> vData) {
// resize to the input data size
m_vData.resize(vData.size());
// Copy the data
memcpy(&m_vData[0], &vData[0], vData.size());
}
/// Implementation of the data function
const unsigned char* CData::Data(size_t& nSize /**< Size of data returned */) {
/*
* Following four methods worked fine on Windows, RedHat, but Failed on Solaris 10 and IBM AIX
*/
// return &m_vData[0];
// return m_vData.data();
// return const_cast<unsigned char*>(reinterpret_cast<const unsigned char *>(m_vData.data()));
// return reinterpret_cast<unsigned char*>(const_cast<unsigned char *>(m_vData.data()));
/* This was tested on following and works fine.
* Windows (Tested on 2008 to 2016, 32/64 bit, R2 versions)
* RedHat 5&7 (32/64 bit)
* Solaris 10 (32/64 bit)
* IBM AIX 7.10
*
*/
return &m_vData.front(); --> This works on windows, redhat, solaris 10, aix
}
/// Main class
int main() {
// Vector of data
vector<unsigned char> vData;
// Add data onto the vector
vData.push_back('a');
vData.push_back('b');
vData.push_back('c');
// Create an instance from the vector of data given
CData oData(vData);
// Get the data from the instance
size_t nSize(0);
cout << "Data:" << oData.Data(nSize) << endl;
return 0;
}
Output:
Data:abc
为 C 库编写 C++ 包装器。在库中有一个函数接受缓冲区作为 unsigned char *
。由于使用 C++,我将我的真实缓冲区存储在 std::vector<char>
中,此外,在包装器 class 中,我还添加了 const
,因为有问题的缓冲区是一个输入缓冲区,它不会被修改。但是我的代码没有编译,demo:
#include <stdio.h>
#include <vector>
void x(unsigned char *s)
{
printf("%s\n", s);
}
int main()
{
const std::vector<char> s(10);
x(reinterpret_cast<unsigned char *>(s.data())); // FAILS
}
id有什么问题?如果我从 const std::vector<char> s(10);
中删除 consts
它会起作用,但我更喜欢那样。
您的错误是因为您将 std::vector
声明为 const
。
如果你去掉常量,它就可以正常工作。 (如所见here)
无论如何,您应该问问自己是否真的需要在数组中存储 char
或 unsigned char
。
如果您想保留 const
,则必须使用 const_cast
,但您的行会变得很长:
x(const_cast<unsigned char*>(reinterpret_cast<const unsigned char *>(s.data())));
如果您有权访问该库,最好将缓冲区标记为 const
(如果它未更改)。
但是,由于它不是 const
,您不能确定它不会被函数修饰,因此,您不应该将 std::vector
保留为 const
.
您必须执行 const_cast
删除常量,然后 reinterpret_cast
将 char *
转换为 unsigned char *
试试这个:x(reinterpret_cast<unsigned char*>(const_cast<char *>(s.data())));
注意:但也请记住 const_cast
只有在转换最初是非常量的变量时才是安全的。请参阅 this 答案。
这就是我在跨平台实施过程中解决同样问题的方法。上述方法在 Windows 和 Linux (Redhat) 上运行良好,但在 Solaris 10 和 IBM AIX 7 上运行不佳。
Solaris 10 使用上述建议的方法给出以下错误。
'nofieldident: data is not a member of const std::vector<unsigned char>'
这是一种处理矢量数据 'const'
ness 的方法,它适用于 Windows、Linux、Solaris
#include <iostream>
#include <vector>
using namespace std;
/// Data Interface, which is visible to the outside
class IDataInterface {
public:
// Get the underlying data as a const data pointer
virtual const unsigned char* Data(size_t& nSize) = 0;
};
/// Implemetation of the IDataInterface
class CData : public IDataInterface {
public:
// Constructor
CData(vector<unsigned char> data);
// Overriden function of the interface
const unsigned char* Data(size_t& nSize);
private:
/// Actual data member
vector<unsigned char> m_vData;
};
/// Constructor implementation
CData::CData(vector<unsigned char> vData) {
// resize to the input data size
m_vData.resize(vData.size());
// Copy the data
memcpy(&m_vData[0], &vData[0], vData.size());
}
/// Implementation of the data function
const unsigned char* CData::Data(size_t& nSize /**< Size of data returned */) {
/*
* Following four methods worked fine on Windows, RedHat, but Failed on Solaris 10 and IBM AIX
*/
// return &m_vData[0];
// return m_vData.data();
// return const_cast<unsigned char*>(reinterpret_cast<const unsigned char *>(m_vData.data()));
// return reinterpret_cast<unsigned char*>(const_cast<unsigned char *>(m_vData.data()));
/* This was tested on following and works fine.
* Windows (Tested on 2008 to 2016, 32/64 bit, R2 versions)
* RedHat 5&7 (32/64 bit)
* Solaris 10 (32/64 bit)
* IBM AIX 7.10
*
*/
return &m_vData.front(); --> This works on windows, redhat, solaris 10, aix
}
/// Main class
int main() {
// Vector of data
vector<unsigned char> vData;
// Add data onto the vector
vData.push_back('a');
vData.push_back('b');
vData.push_back('c');
// Create an instance from the vector of data given
CData oData(vData);
// Get the data from the instance
size_t nSize(0);
cout << "Data:" << oData.Data(nSize) << endl;
return 0;
}
Output:
Data:abc