等同于 C# "unsafe" 代码中的 memset
Equivalent of memset in C# "unsafe" code
我有一个 C# DLL,其代码派生自用托管 C++ 编写的基 class。 (我无法控制基本 class 代码)
这个基 class(在托管 C++ 中)有一个成员
int *buffer
应由派生的 class(在 C# 中)进行内存设置(用零填充)。派生的class知道缓冲区的大小。
我正在使用不安全上下文来访问派生 class 中基 class 的成员 "int *buffer"。请让我知道有什么特殊的方法可以在 c# 的 "unsafe" 上下文中存储缓冲区。
我已经查看了此 What is the equivalent of memset in C#? 的详细信息,但我想知道是否有专门针对 "unsafe" 上下文的内容。
背景:这是一个转换项目,其中派生的class本身之前是在托管C++中。现在我将派生的 class DLL 单独转换为 C#。我也无法控制基本 class 代码!目前的代码流程如下:只有派生的class知道缓冲区的大小。 base class 通过从 derived 获取缓冲区的大小来创建特定大小的内存,但它不会填充零。派生的 class 零首先填充它,然后需要用它的内容适当地填充缓冲区。虽然奇怪,但就是这样。
谢谢!
好吧,有... memset。既然可以 p/invoke 真品,为什么还要接受替代品?
[DllImport("msvcrt.dll", EntryPoint = "memset", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
public static extern IntPtr MemSet(IntPtr dest, int c, IntPtr count);
编辑
正如@Hans 在 OP 评论中正确提到的那样,如果您还不知道 *buffer 的大小,这将毫无用处。
你可以自己编码:
void memset( byte* buffer, int value, int size )
{
for( int i = 0; i < count; i++)
{
*( buffer + i ) = value;
}
}
或者您可以为此使用 API。实际上 RtlZeroMemory 将值设置为零。它实际上不是 memset。
[DllImport("kernel32.dll")]
static extern void RtlZeroMemory(IntPtr dst, int length);
RtlZeroMemory(buffer, bufferLength);
RtlZeroMemory 实际上不是 kernel32 中的入口点。如果你想要那样的东西,请在 C#
中使用它
public static unsafe void ZeroMemory(IntPtr Safebuffer, int count)
{
if (count == 0) return;
byte* buffer = (byte*)Safebuffer.ToPointer();
memset(buffer, count);
}
public static unsafe void ZeroMemory(byte* buffer, int count)
{
if (count == 0) return;
while (count-- > 0)
{
buffer[count] = 0;
}
}
我有一个 C# DLL,其代码派生自用托管 C++ 编写的基 class。 (我无法控制基本 class 代码)
这个基 class(在托管 C++ 中)有一个成员
int *buffer
应由派生的 class(在 C# 中)进行内存设置(用零填充)。派生的class知道缓冲区的大小。
我正在使用不安全上下文来访问派生 class 中基 class 的成员 "int *buffer"。请让我知道有什么特殊的方法可以在 c# 的 "unsafe" 上下文中存储缓冲区。
我已经查看了此 What is the equivalent of memset in C#? 的详细信息,但我想知道是否有专门针对 "unsafe" 上下文的内容。
背景:这是一个转换项目,其中派生的class本身之前是在托管C++中。现在我将派生的 class DLL 单独转换为 C#。我也无法控制基本 class 代码!目前的代码流程如下:只有派生的class知道缓冲区的大小。 base class 通过从 derived 获取缓冲区的大小来创建特定大小的内存,但它不会填充零。派生的 class 零首先填充它,然后需要用它的内容适当地填充缓冲区。虽然奇怪,但就是这样。
谢谢!
好吧,有... memset。既然可以 p/invoke 真品,为什么还要接受替代品?
[DllImport("msvcrt.dll", EntryPoint = "memset", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
public static extern IntPtr MemSet(IntPtr dest, int c, IntPtr count);
编辑
正如@Hans 在 OP 评论中正确提到的那样,如果您还不知道 *buffer 的大小,这将毫无用处。
你可以自己编码:
void memset( byte* buffer, int value, int size )
{
for( int i = 0; i < count; i++)
{
*( buffer + i ) = value;
}
}
或者您可以为此使用 API。实际上 RtlZeroMemory 将值设置为零。它实际上不是 memset。
[DllImport("kernel32.dll")]
static extern void RtlZeroMemory(IntPtr dst, int length);
RtlZeroMemory(buffer, bufferLength);
RtlZeroMemory 实际上不是 kernel32 中的入口点。如果你想要那样的东西,请在 C#
中使用它public static unsafe void ZeroMemory(IntPtr Safebuffer, int count)
{
if (count == 0) return;
byte* buffer = (byte*)Safebuffer.ToPointer();
memset(buffer, count);
}
public static unsafe void ZeroMemory(byte* buffer, int count)
{
if (count == 0) return;
while (count-- > 0)
{
buffer[count] = 0;
}
}