AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 77876062
Accepted
Tom Hosker
Tom Hosker
Asked: 2024-01-25 04:34:26 +0800 CST2024-01-25 04:34:26 +0800 CST 2024-01-25 04:34:26 +0800 CST

Segurança na passagem de números inteiros entre Python e Rust

  • 772

Isso é seguro?

Suponha que eu queira chamar algum código Rust de dentro do Python . Suponha que minha lib.rsaparência seja algo assim:

#[no_mangle]
pub extern fn add(left: i32, right: i32) -> i32 {
    return left+right;
}

E suponho que chamei esse código do Python usando ctypesassim:

import ctypes

def rust_add(left, right):
    rust_lib = ctypes.CDLL("path/to/the/so/file")
    return rust_lib.add(left, right)

Então o acima é seguro?

Um obstáculo antecipado: estouro de número inteiro

Estouro nas entradas

Um problema que até eu - com meu conhecimento extremamente tênue de Rust - posso prever é o estouro de inteiros . Imagino que, se leftou rightfosse maior que 2 ^ 32, isso faria com que coisas ruins acontecessem: ou Rust atingia um erro de tempo de execução (provavelmente) ou apenas retornaria respostas bobas (pior caso). Alguma verificação de tipo no Python, talvez usando NumPy's uint32, seria suficiente para evitar esse problema?

Estouro no funcionamento

Este é mais insidioso: suponha que eu peça, do Python, à minha função Rust para adicionar (2^32)-1 e (2^32)-2. Não deve haver nenhum excesso imediato, mas haverá quando somarmos os dois números. Pelo que entendi, ao atingir tal estouro, Rust entrará em pânico no modo de depuração, mas tentará o seu melhor para continuar no modo de liberação.

Resumo

  • Existe alguma prática bem conhecida para suavizar as dificuldades que surgem ao passar números inteiros entre uma linguagem de largura dinâmica, como Python, e uma de largura fixa, como Rust, além de testes completos?
  • Há algum problema com a passagem de números inteiros entre Rust e Python, além do estouro de números inteiros?
python
  • 1 1 respostas
  • 86 Views

1 respostas

  • Voted
  1. Best Answer
    ChrisB
    2024-01-25T05:52:11+08:002024-01-25T05:52:11+08:00

    Por padrão, ctypesirá converter parâmetros inteiros e valores de retorno de função para seu c_inttipo, cujo tamanho depende da plataforma. Valores que excedam esse tamanho serão truncados. Se c_intnão tiver 32 bits, isso levaria a um comportamento indefinido no sentido Rust (você acaba chamando a função Rust com uma convenção de chamada incorreta). Provavelmente não é isso que você deseja neste caso. (É certo que c_int é de 32 bits nas plataformas de desktop mais comuns).

    Eu ainda recomendo o seguinte código python:

    _rust_lib = ctypes.CDLL("path/to/the/so/file")
    _rust_add = _rust_lib.add
    _rust_add.argtypes = [ctypes.c_int32, ctypes.c_int32]
    _rust_add.restype = ctypes.c_int32
    
    def rust_add(left, right):
        return _rust_add(left, right)
    

    Dessa forma, ctypesconverterá argumentos e tipos de retorno para o tipo inteiro correto, independentemente da plataforma.

    Ele ainda truncará números inteiros maiores e lançará uma exceção para outros tipos de python. Se você quiser ter uma maneira diferente de lidar com esses casos, terá que fazer isso sozinho. Para obter mais detalhes sobre como as conversões de tipo são tratadas, ctypesrecomendo sua excelente documentação .


    Se você quiser apenas ter certeza de que os valores passados ​​​​são corretos e obter algum tipo de exceção em todos os outros casos, você pode escrever uma função simples como esta:

    def sanitize_i32(v):
        # alternatively throw some exception
        assert isinstance(v, int)
        assert v >= -2**31 and v < 2**31
        return v
    
    def rust_add(left, right):
        return _rust_add(sanitize_i32(left), sanitize_i32(right))
    

    Em relação aos overflows no lado do Rust: eles seguirão as regras usuais de overflow de inteiros do Rust (pânico na depuração, complemento de dois no lançamento). Se não é isso que você deseja, codifique alguma outra lógica.

    • 2

relate perguntas

  • Como divido o loop for em 3 quadros de dados individuais?

  • Como verificar se todas as colunas flutuantes em um Pandas DataFrame são aproximadamente iguais ou próximas

  • Como funciona o "load_dataset", já que não está detectando arquivos de exemplo?

  • Por que a comparação de string pandas.eval() retorna False

  • Python tkinter/ ttkboostrap dateentry não funciona quando no estado somente leitura

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve