简体   繁体   English

等效于 C#“不安全”代码中的 memset

[英]Equivalent of memset in C# “unsafe” code

I have a C# DLL, whose code derives from a base class, which is written in managed C++.我有一个 C# DLL,它的代码派生自一个用托管 C++ 编写的基类。 (I don't have any control over the base class code) (我对基类代码没有任何控制权)

This base class (which is in managed C++) has a member这个基类(在托管 C++ 中)有一个成员

int *buffer

is expected to be memset (filled with Zeros) by the derived class (which is in C#).预计由派生类(在 C# 中)被 memset(用零填充)。 The derived class knows the size of the buffer.派生类知道缓冲区的大小。

I am using unsafe context, to access the member "int *buffer" of the base class, in the derived class.我正在使用不安全的上下文来访问派生类中基类的成员“int *buffer”。 Please let me know is there any way special way to memset the buffer in "unsafe" context in c#.请让我知道是否有任何特殊方法可以在 c# 中的“不安全”上下文中设置缓冲区。

I already looked into this What is the equivalent of memset in C#?我已经研究过这个什么是 C# 中的 memset 等价物? for details, but I would like to know is there something specifically for "unsafe" context.有关详细信息,但我想知道是否有专门针对“不安全”上下文的内容。

Background : This is a conversion project, where the derived class itself was in managed c++ before.背景:这是一个转换项目,其中派生类本身之前是在托管c++中。 Now I am converting the derived class DLL alone to C#.现在我将派生类 DLL 单独转换为 C#。 Also I have no control over the base class code!我也无法控制基类代码! The current code flow is as follows: Only the derived class knows the size of the buffer.当前代码流程如下: 只有派生类知道缓冲区的大小。 The base class creates a memory for that particular size, by getting the size of the buffer from derived, but it doesn't zero fill.基类通过从派生中获取缓冲区的大小来为该特定大小创建内存,但它不会零填充。 The derived class Zero fills it first and then need to appropriately fill the buffer with its contents.派生类 Zero 首先填充它,然后需要用其内容适当地填充缓冲区。 Though strange, that is how it is.虽然很奇怪,但就是这样。

Thanks!谢谢!

Well, there is... memset.嗯,有... memset。 Why settle for a replacement when you can p/invoke the real thing?当您可以调用/调用真实的东西时,为什么还要更换?

[DllImport("msvcrt.dll", EntryPoint = "memset", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
public static extern IntPtr MemSet(IntPtr dest, int c, IntPtr count);

Taken from pinvoke.net摘自pinvoke.net

edit编辑

As @Hans rightfully mentions in the OP comments, this is useless if you don't already know the size of *buffer.正如@Hans 在 OP 评论中正确提到的那样,如果您还不知道 *buffer 的大小,这将毫无用处。

You can code it on your own:你可以自己编码:

void memset( byte* buffer, int value, int size )
{
    for( int i = 0; i < count; i++)
    {
        *( buffer + i ) = value;
    }
}

Or you can use an API for this.或者您可以为此使用 API。 Actually RtlZeroMemory sets values to zero.实际上 RtlZeroMemory 将值设置为零。 It's not actually memset.它实际上不是 memset。

[DllImport("kernel32.dll")]
static extern void RtlZeroMemory(IntPtr dst, int length);

RtlZeroMemory(buffer, bufferLength);

RtlZeroMemory is not actually an entry point in kernel32. RtlZeroMemory 实际上并不是 kernel32 中的入口点。 If yo want something like that, use this in C#如果你想要这样的东西,在 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;
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM