标准仿C语言 memset、memcpy、memmove函数
前段时间,移植了C的网络加解密算法到C#,其中遇到很多问题,核心问题大多都是字节拷贝问题,今天有时间整理了一下相关的API,废话不多说直接贴源码:(值得注意的是memmove函数,支持数据重叠,详情参照http://blog.csdn.net/yujun_wu/article/details/4999565)
一> C++版
/*
* @brief: 将dst中当前位置后面的 count 个字节用 val 替换并返回 dst
* @param s - 数据内存的起始地址
* @param c - 替换后的值
* @param n - 要替换的长度
* @return 返回原数据首地址
*/
void* memset(void* s, int c, size_t n)
{
assert(s);
unsigned char* p = (unsigned char*)s;
while (n > 0)
{
*p++ = (unsigned char)c;
--n;
}
return s;
}
/*
* @brief: 用于从src拷贝count个字节到dest,如果目标区域和源区域有重叠的话
,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中。
但复制后src内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同
* @param dst - 目标内存地址
* @param src - 原内存地址
* @param count - 要拷贝的长度
* @return 返回dst地址
*/
void* memmove(void* dst, const void* src, size_t count)
{
assert(dst);
assert(src);
void * ret = dst;
if (dst <= src || (char *)dst >= ((char *)src + count))
{
while (count--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
}
else
{
dst = (char *)dst + count - 1;
src = (char *)src + count - 1;
while (count--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst - 1;
src = (char *)src - 1;
}
}
return(ret);
}
/*
* @brief: 用于从src拷贝count个字节到dest(不能包含重叠)
* @param dst - 目标内存地址
* @param src - 原内存地址
* @param count - 要拷贝的长度
* @return 返回dst地址
*/
void* memcpy(void* dst, const void* src, size_t count)
{
assert(dst);
assert(src);
void* ret = dst;
/*
* copy from lower addresses to higher addresses
*/
while (count--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
return(ret);
}
二> C#版
// 标准仿C memcpy函数
unsafe public void* memcpy(void* dst, void* src, uint count)
{
System.Diagnostics.Debug.Assert(dst != null);
System.Diagnostics.Debug.Assert(src != null);
void* ret = dst;
/*
* copy from lower addresses to higher addresses
*/
while (count-- > 0)
{
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
return (ret);
}
// 标准仿C memmove函数
unsafe public void* memmove(void* dst, void* src, uint count)
{
System.Diagnostics.Debug.Assert(dst != null);
System.Diagnostics.Debug.Assert(src != null);
void* ret = dst;
if (dst <= src || (char *)dst >= ((char *)src + count))
{
while (count-- > 0)
{
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
}
else
{
dst = (char *)dst + count - 1;
src = (char *)src + count - 1;
while (count-- > 0)
{
*(char*)dst = *(char*)src;
dst = (char*)dst - 1;
src = (char*)src - 1;
}
}
return(ret);
}
// 标准仿C memset函数
unsafe public void* memset(void* s, int c, uint n)
{
byte* p = (byte*)s;
while (n > 0)
{
*p++ = (byte)c;
--n;
}
return s;
}
来源:CSDN
作者:__Always
链接:https://blog.csdn.net/dominating_/article/details/55103461