Передача нулевых аргументов в методы C #

В вашем коде есть признаки того, что вы, возможно, использовали учебник Linux при создании кода для OS / X (BSD). Linux и OS / X отличаются соглашениями SYSCALL . В 32-битных программах OS / X для int 0x80 требуются параметры (за исключением того, что syscall в EAX ) передается в стеке.

Важные вещи, о которых нужно знать с помощью 32 -бит SYSCALL s через int 0x80 в OS / X:

  • аргументы, переданные в стек, нажатые справа налево
  • вы должны выделить дополнительные 4 байта ( DWORD ) в стеке после того, как вы нажмете все аргументы
  • номер syscall в регистре eax
  • вызов прерыванием 0x80
blockquote>

После нажатия аргументов в стеке в обратном порядке для int 0x80 вы должны выделить дополнительные 4 байта ( DWORD ), в стеке. Значение в этой ячейке памяти в стеке не имеет значения. Это требование является артефактом из старого соглашения UNIX .

Список номеров SYSCALL и их параметров можно найти в APPLE файлы заголовков . Вам понадобятся эти SYSCALL s:

1 AUE_EXIT    ALL { void exit(int rval); }
3 AUE_NULL    ALL { user_ssize_t read(int fd, user_addr_t cbuf, user_size_t nbyte); } 
4 AUE_NULL    ALL { user_ssize_t write(int fd, user_addr_t cbuf, user_size_t nbyte); } 
blockquote>

Я прокомментировал некоторый пример кода, который будет похож по функциональности на то, что вы, возможно, были пытающихся достичь:

section .data
    ;New line string
    NEWLINE: db 0xa, 0xd
    LENGTH: equ $-NEWLINE

section .bss
    INPT: resd 1

global _start

section .text
_start:
    and     esp, -16      ; Make sure stack is 16 byte aligned at program start
                          ;     not necessary in this example since we don't call 
                          ;     external functions that conform to the OS/X 32-bit ABI

    push    dword 1       ; Read 1 character
    push    dword INPT    ; Input buffer
    push    dword 0       ; Standard input = FD 0
    mov     eax, 3        ; syscall sys_read
    sub     esp, 4        ; Extra 4 bytes on stack needed by int 0x80
    int     0x80
    add     esp, 16       ; Restore stack

    push    dword 1       ; Print 1 character
    push    dword INPT    ; Output buffer = buffer we read characters into
    push    dword 1       ; Standard output = FD 1
    mov     eax, 4        ; syscall sys_write
    sub     esp, 4        ; Extra 4 bytes on stack needed by int 0x80
    int     0x80
    add     esp, 16       ; Restore stack

    push    dword LENGTH  ; Number of characters to write
    push    dword NEWLINE ; Write the data in the NEWLINE string
    push    dword 1       ; Standard output = FD 1
    mov     eax, 4        ; syscall sys_write
    sub     esp, 4        ; Extra 4 bytes on stack needed by int 0x80
    int     0x80
    add     esp, 16       ; Restore stack

    push    dword 0       ; Return value from program = 0
    mov     eax, 1        ; syscall sys_exit
    sub     esp, 4        ; Extra 4 bytes on stack needed by int 0x80
    int     0x80

and esp, -16 необходимо, только если вам нужно выровнять стек с 16-байтовой границей в качестве базовой линии для будущих операций стека. Если вы намереваетесь вызывать внешние функции, которые соответствуют OS / X 32-битовому ABI , ожидается, что стек будет выровнен по 16 байт непосредственно перед функцией CALL . Это выравнивание не требуется для системных вызовов через int 0x80.

Вы должны иметь возможность собирать и связывать его с:

nasm -f macho32 test.asm -o test.o
ld -macosx_version_min 10.9.0 -o test test.o -e _start -lSystem

И запустите его с помощью:

./test

29
задан Niko Gamulin 7 November 2008 в 09:13
поделиться

7 ответов

Да. В .NET есть два типа типов: ссылочные типы и типы значений.

Типы ссылок (обычно классы) всегда упоминаются ссылками, поэтому они поддерживают null без какой-либо дополнительной работы. Это означает, что если тип переменной является ссылочным типом, переменная автоматически становится ссылкой.

Типы значений (например, int) по умолчанию не имеют понятия нуля. Тем не менее, есть обертка для них под названием Nullable. Это позволяет вам инкапсулировать ненулевой тип значения и включать нулевую информацию.

Использование немного отличается, хотя.

// Both of these types mean the same thing, the ? is just C# shorthand.
private void Example(int? arg1, Nullable<int> arg2)
{
    if (arg1.HasValue)
        DoSomething();

    arg1 = null; // Valid.
    arg1 = 123;  // Also valid.

    DoSomethingWithInt(arg1); // NOT valid!
    DoSomethingWithInt(arg1.Value); // Valid.
}
71
ответ дан Sander 7 November 2008 в 09:13
поделиться

Я думаю, что ближайший эквивалент C # int* будет ref int?. Потому что ref int? позволяет вызываемому методу передавать значение обратно вызывающему методу.

int*

  • Может быть нулевым.
  • Может быть ненулевым и указывать на целочисленное значение.
  • Если не ноль, значение может быть изменено , и изменение распространяется на вызывающего.
  • Установка в ноль не передается вызывающей стороне .

ref int?

  • Может быть нулевым.
  • Может иметь целочисленное значение.
  • Значение всегда можно изменить , и это изменение распространяется на вызывающего.
  • Значение может быть установлено равным нулю, и это изменение также будет распространяться на вызывающего абонента .
  • [1 125]
6
ответ дан mackenir 7 November 2008 в 09:13
поделиться

Вы можете использовать NullableValueTypes (например, int?) Для этого. Код будет выглядеть так:

private void Example(int? arg1, int? arg2)
{
    if(!arg1.HasValue)
    {
        //do something
    }
    if(!arg2.HasValue)
    {
        //do something else
    }
}
5
ответ дан MADMap 7 November 2008 в 09:13
поделиться

Из C # 2.0:

private void Example(int? arg1, int? arg2)
{
    if(arg1 == null)
    {
        //do something
    }
    if(arg2 == null)
    {
        //do something else
    }
}
3
ответ дан Marcin K 7 November 2008 в 09:13
поделиться

На вопрос ОП уже получен хороший ответ, но заголовок достаточно широк, так что я думаю, что он выигрывает от следующего учебника:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace consolePlay
{
    class Program
    {
        static void Main(string[] args)
        {
            Program.test(new DateTime());
            Program.test(null);
            //Program.test(); // <<< Error.  
            // "No overload for method 'test' takes 0 arguments"  
            // So don't mistake nullable to be optional.

            Console.WriteLine("Done.  Return to quit");
            Console.Read();
        }

        static public void test(DateTime? dteIn)
        {
            Console.WriteLine("#" + dteIn.ToString() + "#");
        }
    }
}

выход:

#1/1/0001 12:00:00 AM#
##
Done.  Return to quit
2
ответ дан ruffin 7 November 2008 в 09:13
поделиться

Начиная с C # 2.0, вы можете использовать универсальный тип Nullable Nullable, а в C # есть условное обозначение типа, за которым следует?

, например

private void Example(int? arg1, int? arg2)
{
    if(arg1 == null)
    {
        //do something
    }
    if(arg2 == null)
    {
        //do something else
    }
}
3
ответ дан user35412 7 November 2008 в 09:13
поделиться

Вы можете использовать 2 способа: int? или Nullable, оба имеют одинаковое поведение. Вы можете сделать микс без проблем, но лучше сделать код максимально чистым.

Вариант 1 (с?):

private void Example(int? arg1, int? arg2)
    {
        if (arg1.HasValue)
        {
            //do something
        }
        if (arg1.HasValue)
        {
            //do something else
        }
    }

Вариант 2 (с нулевым значением):

private void Example(Nullable<int> arg1, Nullable<int> arg2)
    {
        if (arg1.HasValue)
        {
            //do something
        }
        if (arg1.HasValue)
        {
            //do something else
        }
    }

В C # 4.0 появился новый способ сделать то же самое с большей гибкостью в этом случае платформа предлагает необязательные параметры со значениями по умолчанию , таким образом, вы можете установить значение по умолчанию, если метод вызывается без всех параметров.

Вариант 3 (со значениями по умолчанию)

private void Example(int arg1 = 0, int arg2 = 1)
    {
        //do something else
    }
0
ответ дан juancalbarran 7 November 2008 в 09:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: