我正在开发的项目需要从C ++概念到C的一堆转换。在这个用例中,调用者负责管理内存缓冲区。然后,他调用该函数并提供double类型的数组和他分配的内存量。然后该函数用向量中的所有双精度填充他的数组缓冲区。这是我对该功能的第一次拍摄,但我不确定它是否正确。由于我对C不太熟悉,我确信有错误。我这样做了吗?那么在末尾添加空终止\0
怎么样?
void getMoments(uint32_t & bufferSize,
double * moments)
{
if ( bufferSize < (vec.size() * sizeof(double)) + 1 )
{
// set error: bufferSize is not large enough to copy elements of vector.
}
typedef std::vector<double>::const_iterator it_type;
for (it_type it = vec.begin(); it != vec.end(); ++it)
{
double e = *it;
std::memcpy(moments, &e, sizeof(double));
}
// How do I add the null terminating \0?
}
顺便说一句,bufferSize是通过引用传递的,因为FORTRAN是一个客户端,语言要求所有内容都通过引用传递。
让我对C数组感到困惑的是指针的概念(或缺乏概念)。我们怎么知道我们在C阵列中的位置?换句话说,每当我调用memcpy时,它应该从数组的开头开始写,从而覆盖我以前写的字节吗?
答案 0 :(得分:3)
指针可以用作输出迭代器:
if (bufferSize < vec.size() * sizeof(double))
{
// error: buffer too small
return;
}
std::copy(vec.begin(), vec.end(), moments);
注意:如果你将指针传递给double,我会用双精度表示缓冲区/数组大小,而不是字符(字节)。
答案 1 :(得分:1)
我不知道为什么你需要null终止双精度数组,所以我把它删除了。
完整代码:
void getMoments(uint32_t & bufferSize, double * moments)
{
if ( bufferSize < (vec.size() * sizeof(double)) )
{
// set error: bufferSize is not large enough to copy elements of vector.
}
typedef std::vector<double>::const_iterator it_type;
for (it_type it = vec.begin(); it != vec.end(); ++it)
{
*moments++ = *it;
}
}
答案 2 :(得分:1)
一种可能的解决方案:
#include <vector>
#include <algorithm>
...
int getMoments(uint32_t* bufferSize,
double * moments)
{
std::vector<double> vec = ...
if (*bufferSize/sizeof(double) < vec.size())
return -1;
std::copy(vec.begin(), vec.end(), moments);
return 0;
}
注意: C中没有“引用”。因此,您的C API必须将参数 bufferSize 作为指针传递。