Do not use OutAttribute on string parameters for P/Invokes

이 페이지는 아직 영어로 제공되지 않습니다. 번역 작업 중입니다.
현재 번역 프로젝트에 대한 질문이나 피드백이 있으신 경우 언제든지 연락주시기 바랍니다.

Metadata

ID: csharp-best-practices/outattr-on-pinvoke

Language: C#

Severity: Warning

Category: Best Practices

Description

The OutAttribute on string parameters for P/Invoke methods is not recommended because strings in .NET are immutable. When you pass a string to a method as an output parameter, it’s not possible to modify the original string. This can lead to unexpected behaviors and bugs in your code.

This rule is important because it helps to prevent these issues, ensuring that your P/Invoke methods work correctly and as expected. Adhering to this rule will result in more robust and maintainable code.

How to remediate

Use StringBuilder instead of string for output parameters. The StringBuilder class is mutable and can handle the modifications made by the P/Invoke method. In the compliant code example, StringBuilder is used with the GetComputerName method, and the method is able to modify the StringBuilder object and reflect the changes in the calling code.

Non-Compliant Code Examples

using System;
using System.Runtime.InteropServices;

class Program
{
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
    public static extern void GetComputerName([Out] string name, ref int size);

    [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
    public static void GetComputerNameInternal([Out] string name, ref int size){
        
    }

    static void Main()
    {
        int size = 256;
        string name = new string('\0', size);
        GetComputerName(name, ref size);
        Console.WriteLine(name);
    }
}

Compliant Code Examples

using System;
using System.Runtime.InteropServices;
using System.Text;

class Program
{
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
    public static extern bool GetComputerName(StringBuilder name, ref int size);

    static void Main()
    {
        int size = 256;
        StringBuilder name = new StringBuilder(size);
        if (GetComputerName(name, ref size))
        {
            Console.WriteLine(name.ToString());
        }
        else
        {
            Console.WriteLine("Failed to get computer name.");
        }
    }
}
https://static.datadoghq.com/static/images/logos/github_avatar.svg https://static.datadoghq.com/static/images/logos/vscode_avatar.svg jetbrains

Seamless integrations. Try Datadog Code Security

PREVIEWING: aleksandr.pasechnik/svls-6807-lambda-fips