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 / 问题

All perguntas(coding)

Martin Hope
ViperZer0
Asked: 2025-04-26 00:46:44 +0800 CST

Como o Rust sabe o tamanho que cada tipo de ponteiro inteligente deve ter?

  • 8

No código Rust a seguir, um Boxou Rccontendo um u32tem 8 bytes, enquanto um Boxou Rccontendo uma fatia tem 16 bytes. Eu entendo o porquê; um ponteiro inteligente apontando para uma área de memória de tamanho dinâmico (como uma fatia) incluirá o comprimento dessa área de memória, além do endereço.

fn main()
{
    println!("Size of Box<u32>: {} bytes", std::mem::size_of::<Box<u32>>()); // 8
    println!("Size of Box<[u32]>: {} bytes", std::mem::size_of::<Box<[u32]>>()); // 16
    println!("Size of Box<str>: {} bytes", std::mem::size_of::<Box<str>>()); // 16

    println!("Size of Rc<u32>: {} bytes", std::mem::size_of::<Rc<u32>>()); // 8 
    println!("Size of Rc<[u32]>: {} bytes", std::mem::size_of::<Rc<[u32]>>()); // 16
    println!("Size of Rc<str>: {} bytes", std::mem::size_of::<Rc<str>>()); // 16
}

Minha pergunta é como o compilador do Rust sabe qual deve ser o tamanho do ponteiro e como esse comprimento adicional é realmente usado ou interpretado.

Para começar, aqui está meu melhor palpite sobre o que está acontecendo com o tamanho do ponteiro. Ambos Rce Boxtêm as seguintes estruturas:

pub struct Box<T: ?Sized, A: Allocator = Global>(Unique<T>, A);
pub struct Rc<T: ?Sized, A: Allocator = Global> {
    ptr: NonNull<RcInner<T>>,
    phantom: PhantomData<RcInner<T>>,
    alloc: A,
}

Presumo que, de alguma forma, o Allocatortipo esteja dando ao Box/ Rc8 bytes extras de espaço para o comprimento, mas não sei como isso está realmente acontecendo. Analisei o código do alocador, mas não entendi o que a inclusão do alocador aqui realmente faz. Se eu fosse criar meu próprio tipo de ponteiro/contêiner, incluir o Allocatortipo na minha struct seria suficiente para ter esse comportamento?

Quanto ao modo como o comprimento é usado, meu entendimento é que tanto Box<T>e Rc<T>podem ser coagidos de forma transparente para &T, e &Té um tipo primitivo que o compilador mais ou menos espera que seja um ponteiro para uma única unidade de dados, ou um ponteiro e um comprimento para uma matriz de dados, mas nesse caso, a Derefimplementação me confunde.

impl<T: ?Sized, A: Allocator> Deref for Rc<T, A> {

    type Target = T;

    #[inline(always)]
    fn deref(&self) -> &T {
        &self.inner().value
    }
}

Sinto que esperaria que isso, de alguma forma, "perdesse" a informação sobre o comprimento, já que essa informação está incluída com o Rce não com o RcInnerou com o valor T. Mas, em vez disso, o compilador magicamente sabe disso, porque Rc<[T]>é um ponteiro, assim como &[T], ele sabe que Rctambém tem esse comprimento um tanto oculto após o endereço, embora Rcnunca o inclua explicitamente. Eu sei que o comprimento não é armazenado com , [T]como você poderia esperar, ele é armazenado na pilha com o endereço de [T], seja por meio de um Box, um Rc, ou uma referência simples.

Então essas são minhas duas perguntas: como os dados adicionais para um ponteiro gordo são definidos/estabelecidos na própria estrutura de dados e como o Rust sabe que um tipo como Rcou Boxdeve ser não apenas um ponteiro, mas um ponteiro gordo com informações adicionais sobre o comprimento?

Aqui estão algumas perguntas semelhantes que me ajudaram a entender como fatias/ponteiros/ponteiros grossos funcionam como pano de fundo para isso:

  • Qual é a diferença entre uma fatia e uma referência em Rust?
  • O que é um "ponteiro gordo"?
  • Qual é a diferença entre uma fatia e uma matriz?
pointers
  • 1 respostas
  • 68 Views
Martin Hope
Jackoo
Asked: 2025-04-25 17:21:15 +0800 CST

Por que é um problema chamar uma função inline estática em uma função inline externa?

  • 8
// lib.h
#pragma once
static inline int static_inline(int x) { return x; }
inline int extern_inline(int x) { return static_inline(x); }
// lib.c
#include "lib.h"
extern inline int extern_inline(int x);
// app.c
#include "lib.h"

Ao compilar app.c, o gcc emite este aviso:

'static_inline' é estático, mas é usado na função inline 'extern_inline', que não é estática.

Por que isso é um problema? Meu raciocínio é: em app.c, se extern_inline não for incorporado, torna-se uma chamada de função e seus detalhes de implementação (chamadas static_inline) podem ser ignorados. Se extern_inline for incorporado, tem a definição completa e as definições em outras unidades de tradução também podem ser ignoradas.

c
  • 1 respostas
  • 75 Views
Martin Hope
Lance Pollard
Asked: 2025-04-25 15:32:42 +0800 CST

Como criar um layout que tenha apenas todos os tamanhos de linhas pares ou ímpares e mude em apenas 2?

  • 8

Tenho iterado com o Claude 3.7 Sonnet e o ChatGPT 4o por dias e dias, tentando fazer com que fique exatamente como eu quero, mas ele continua cometendo erros no algoritmo e, de vez em quando, cometendo os mesmos erros, basicamente em um círculo vicioso.

Como faço para criar um "layout" (matriz de inteiros), que representa uma grade, que tem as seguintes restrições:

  1. A função é generateGridLayout(n, minColumns, maxColumns), onde na prática ela é normalmente chamada de gen(n, 3, 7), mas em teoria poderia ser qualquer coisa que formaria uma grade legal, gen(n, 2, 256)como o intervalo máximo.
  2. Ele deve manipular um número arbitrário de elementos (digamos, até Number.MAX_SAFE_INTEGER, que é 9007199254740991, mas, na prática, meus "layouts de grade" terão apenas até 1000 itens).
  3. Se o número de itens nfor ímpar, cada linha deverá ter apenas um número ímpar de valores. Se nfor par, cada linha poderá ter números pares ou ímpares (pense em 30, podem ser 10 linhas de 3, ou 3 linhas de 10).
  4. As linhas só podem diferir 2em tamanho, sempre decrescente. Elas nunca podem diferir em 3, 4, etc. Isso significa que 7 NÃO PODE ser [5, 2] ou [4, 4, 1], pois esses têm saltos > 2. Só pode ser [7] ou [3, 3, 1], se gen(7, 3, 7).
  5. (nota meta: isso é para um layout de interface de usuário, então é baseado no tamanho da janela de visualização/contêiner, então se dissermos "máximo 7", mas houver espaço apenas para 5, ele definirá o máximo como 5, mas esse fato não é realmente relevante para a solução)
  6. Se dissermos "máximo é 7", mas houver um número par de itens, e o número par não puder satisfazer "todas as linhas pares ou ímpares", então tente maxColumns - 1, e assim por diante, até minColumns.
  7. Importante: deve minimizar o número de linhas pequenas. Portanto, para 29, com 6 maxColumns, deve ser [5, 5, 5, 5, 5, 3, 1], e não [5, 5, 5, 5, 3, 3, 3]. Ou seja, maximiza o número de linhas grandes e minimiza o número de linhas pequenas. Da mesma forma, para 29, definitivamente não deve ser [5, 5, 5, 5, 3, 3, 1, 1, 1].

Aqui estão alguns exemplos para demonstrar o objetivo:

31
[5, 5, 5, 5, 5, 3, 3]
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1]

30
[5, 5, 5, 5, 5, 5]
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3]

29
[5, 5, 5, 5, 5, 3, 1]
[3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1]

28
[6, 6, 6, 6, 4]
[4, 4, 4, 4, 4, 4, 4]

27
[5, 5, 5, 5, 3, 3, 1]
[3, 3, 3, 3, 3, 3, 3, 3, 3]

26
[6, 6, 6, 4, 2, 2]
[4, 4, 4, 4, 4, 4, 4]

23
[5, 5, 5, 5, 3]
[3, 3, 3, 3, 3, 3, 3, 1, 1]

Elas mostram, se 5 ou 6 forem o máximo de colunas, o que ele faria, e o que deveria fazer se 4 ou 3 forem o máximo de colunas.

Por exemplo, 26 em 7 colunas no máximo NÃO devem ser:

[6, 6, 6, 6, 2] # jumps more than 2
[4, 4, 4, 4, 4, 4, 2] # doesn't maximize maxColumns

O ideal seria:

[6, 6, 6, 4, 2, 2] # jumps max 2, maximizes large columns, minimizes small columns.

Aqui está minha solução atual:

log(29, 2, 7)
log(29, 2, 6)
log(29, 2, 5)
log(29, 2, 4)
log(44, 2, 3)

function distributeGridLayout(
  length,
  minColumns,
  maxColumns
) {
  function recur(
    dp,
    length,
    width,
  ) {
    if (length == 0) {
      return []
    }

    if (length < width - 2 || width <= 0) {
      return
    }

    if (dp[width].has(length)) {
      return
    }

    dp[width].add(length)

    for (let i = 0; i < 2; i++) {
      let result = recur(dp, length - width, width)
      if (result) {
        return [width, ...result]
      }
      width -= 2
    }

    return
  }

  if (length <= maxColumns) {
    return [length]
  }

  if (maxColumns >= 3 && length === 7) {
    return [3, 3, 1]
  }

  if (maxColumns >= minColumns && length % maxColumns === 0) {
    const result = []
    while (length) {
      result.push(maxColumns)
      length -= maxColumns
    }
    return result
  }

  if (maxColumns > 4) {
    if (maxColumns > minColumns && length % (maxColumns - 1) === 0) {
      const result = []
      maxColumns--
      while (length) {
        result.push(maxColumns)
        length -= maxColumns
      }
      return result
    }
  }

  const dec = 2 - (length % 2)

  maxColumns -= maxColumns % dec

  const dp = Array.from(
    { length: maxColumns + 1 },
    () => new Set(),
  )

  for (let width = maxColumns; width > 0; width -= dec) {
    const result = recur(dp, length - width, width)
    if (result) {
      if (width <= minColumns) {
        return
      }
      return [width, ...result]
    }
  }

  return
}

function log(n, min, max) {
  const grid = distributeGridLayout(n, min, max)
  console.log(`gen(${n}, ${min}, ${max})`, grid)
}

Isso funciona para a maioria, como este layout tibetano (29 caracteres):

Mas não está funcionando para este layout tailandês (44 caracteres, em 2-3 colunas), aqui está o final (na minha interface, se o algoritmo retornar indefinido, ele volta para um layout de grade básico):

O que preciso mudar exatamente para que isso sempre se ajuste às minhas regras? O layout 44 de 3 no máximo e 2 minutos deve ser basicamente um layout de 2 colunas...

javascript
  • 1 respostas
  • 85 Views
Martin Hope
F. X. P.
Asked: 2025-04-25 12:39:42 +0800 CST

Por que o Python não permite o encadeamento dos descritores `@classmethod` e `@property` desde a versão 3.13? Qual é a solução definitiva para a propriedade de classe?

  • 8

(Sei que há perguntas semelhantes já respondidas, mas minha pergunta se concentra mais no motivo por trás da solução do que na solução em si).

Eu precisava de algo como uma "propriedade de classe" em Python e pesquisei em perguntas existentes. Algumas respostas oferecem uma solução alternativa, mas não consigo entender por que o Python desativou o encadeamento @classmethode @property. Existe alguma explicação para isso?

Além disso, descobri que todas as soluções disponíveis atualmente têm limitações, listadas abaixo. As postagens que li incluem:

  • Uma resposta que aponta que o encadeamento @classmethode @propertyfoi desabilitado desde o Python 3.13
  • Outra solução que define um descritor personalizado classproperty. Mas esta solução alternativa não impede modificações. Por exemplo, o código a seguir, derivado da resposta original, não gerará uma exceção quando xhouver tentativa de modificação.
    class classproperty(property):
        def __get__(self, owner_self, owner_cls):
            return self.fget(owner_cls)
    
        def __set__(self, instance, value):
            raise AttributeError("can't set attribute")
    
    
    class C(object):
        @classproperty
        def x(cls):
            return 1
    
    
    print(C.x)
    C.x = 2
    print(C.x) # Output: 2
    # no exception raised
    # cannot prevent modification
    
  • Uma solução é escrever a propriedade de classe na metaclasse. Este método impede com sucesso tentativas de modificação, mas com este método, o acesso às variáveis ​​de classe só será possível via classe, não via instância.
    class CMeta(type):
        @property
        def x(cls):
            return 1
    
    
    class C(object, metaclass=CMeta): ...
    
    
    print(C.x)
    # C.x = 2
    # AttributeError: property 'x' of 'CMeta' object has no setter
    # print(C().x)
    # AttributeError: 'C' object has no attribute 'x'
    

Então, existe uma maneira definitiva de resolver todos os problemas mencionados acima e permitir uma implementação de propriedade de classe que satisfaça as duas condições a seguir?

  • Pode evitar tentativas de modificação
  • Pode ser acessado tanto da classe quanto da instância
python
  • 1 respostas
  • 97 Views
Martin Hope
Dominik Kaszewski
Asked: 2025-04-25 03:57:44 +0800 CST

Trocadilhos baseados em união e código C/C++ misto

  • 8

Tenho uma base de código C que usa uniões para trocadilhos de tipos. Estou então testando esse código em C++ com o gmock.

Sei que o trocadilho baseado em união é ilegal em C++ , então queria ter certeza de que meu uso é seguro:

// sum_halves.h
#include <stdint.h>
uint32_t sum_halves(unit64_t i);
// sum_halves.c
#include "sum_halves.h"
uint32_t sum_halves(unit64_t i) {
    union {
        uint64_t u64;
        uint32_t u32[2];
    } u;
    u.u64 = i;
    return u.u32[0] + u.u32[1];
}
// sum_halves_test.cpp
extern "C" {
#include "sum_halves.h"
}
#include <gtest/gtest.h>

TEST(sum_halves_test, two_plus_two_is_five) {
    EXPECT_EQ(sum_halves(0x0000'0002'0000'0003), 5);
}

Pelo que entendi, como sum_halves.cé compilado como um programa em C, o trocadilho baseado em união está correto, mesmo que eu posteriormente chame essa função a partir de código C++. Mas se eu criasse sum_halvesuma função inline, ela seria compilada como código C++ em *.cpparquivos, resultando em Comportamento Indefinido. extern "C"Isso não ajuda, pois afeta apenas a vinculação, não a compilação.

Se estiver correto, existe alguma solução alternativa para o caso inline? Uma flag do compilador GCC ou Clang ou #pragmapara permitir trocadilhos baseados em união em uma função específica?

c++
  • 3 respostas
  • 217 Views
Martin Hope
Fedor
Asked: 2025-04-25 03:43:56 +0800 CST

Por que a cópia dos elementos do vetor pode ser feita com o argumento lvalue not-const?

  • 8

Se alguém copia um std::vectorem outro, ou copia elementos de um std::vectorem um bloco maior ( reserve) ou menor ( shrink_to_fit) da memória heap, qual construtor do tipo do elemento é chamado?

No programa de exemplo:

#include <vector>
#include <iostream>

struct A {
    A() {}
    A(A&) { std::cout << "A(A&) "; }
    A(const A&) { std::cout << "A(const A&) "; }
};

int main() {
    std::vector<A> v(1);
    v.reserve(10);
    auto w = v;
    v.shrink_to_fit();
}

Eu esperaria ver A(const A&) A(const A&) A(const A&)uma saída. Mas, na realidade, as implementações da biblioteca padrão divergem:

  • libc++impressões A(const A&) A(A&) A(const A&),
  • libstdc++impressões A(const A&) A(const A&) A(A&),
  • e o Microsoft STL imprime A(A&) A(A&) A(A&).

Demonstração online: https://gcc.godbolt.org/z/TTqxv9sd3

É correto supor que se o construtor de not- constlvalue for chamado, o código do usuário terá permissão para modificar seu argumento (pelo menos temporariamente)?

c++
  • 1 respostas
  • 92 Views
Martin Hope
jeffgoblue
Asked: 2025-04-25 03:08:04 +0800 CST

Trace a regressão linear de melhor ajuste com a inclinação definida para um valor fixo (m=1)

  • 8

Atualmente, estou usando o R 4.4.3 no Windows 11. Estou plotando o seguinte conjunto de dados ggplot2e realizando uma regressão linear com geom_smooth:

df <- data.frame(A= c(1.313, 1.3118, 1.3132, 1.3122, 1.3128, 1.3061, 1.3051, 1.3052, 1.3069, 1.3053, 1.3072, 1.3006, 1.3246, 
1.3229, 1.3254, 1.3239, 1.3222, 1.3155, 1.313, 1.3147, 1.3174, 1.3174, 1.3188, 1.3134),
B=c(1.3165, 1.316, 1.3176, 1.316, 1.3169, 1.3104, 1.3094, 1.3095, 1.3107, 1.3101, 1.3112, 1.3047, 
1.3285, 1.3271, 1.3297, 1.3274, 1.3261, 1.3192, 1.318, 1.319, 1.322, 1.3215, 1.3232, 1.3172))

Estou usando stat_regline_equationo ggpubrpacote para imprimir a regressão e também estou imprimindo uma reta de referência de y=x usando geom_abline. O código do meu gráfico é mostrado abaixo:

ggplot(df,  aes(x=A,  y=B)) +
    geom_point() +
    geom_abline(slope=1,  intercept=0) +
    geom_smooth(color='red',  method = lm,  se = FALSE,  formula = y~x) +
    stat_regline_equation(label.x=1.31,  label.y=1.325) +
    coord_equal()

O coord_equalcomando força a escala dos dois eixos a serem iguais.

Gráfico típico com regressão e linha y=x

Tudo isso é muito bom, mas o que preciso fazer é encontrar a equação de regressão a partir desse conjunto de dados se a inclinação da reta for fixada em 1, ou seja, espero uma equação que se pareça com y=b + 1xonde b é a interceptação se a regressão for forçada a ter uma inclinação m=1.

Este é um pequeno exemplo; meu conjunto de dados completo provavelmente terá vários gráficos semelhantes gerados com facet_wrapou facet_grid, então espero que haja uma maneira de fazer isso de forma que essa regressão de declive forçado possa ser repetida em vários painéis.

Do ponto de vista prático, os dados representam medições de vários itens medidos na Ferramenta A e na Ferramenta B. Portanto, este é um gráfico de correlação entre as duas ferramentas. Idealmente, elas mediriam de forma idêntica, mas está claro que a Ferramenta B mede um pouco mais que a Ferramenta A. A equação de regressão me fornece essa correlação, mas prefiro assumir um deslocamento linear (o que é razoável em um pequeno intervalo). Daí meu desejo de fixar a regressão em m = 1 e calcular o intercepto, que será efetivamente o deslocamento médio.

Não estou preso a geom_smoothou stat_regline_equation, então se houver melhores ferramentas de regressão disponíveis que sejam compatíveis com ggplot2isso e possam ajudar, estou todo ouvidos.

Obrigado!

  • 1 respostas
  • 76 Views
Martin Hope
Banone
Asked: 2025-04-24 20:45:18 +0800 CST

Oracle-DB, Unindo 3 Tabelas Limitando a segunda sem usar LATERAL() ou aninhamento

  • 8

Olá a todos, estou com um problema específico. Estou usando o Oracle DB

Para o exemplo, usarei o banco de dados Northwind.

Quero unir as tabelas: Clientes , Pedidos , Detalhes do pedido e Produtos .

Solução simples:

SELECT Customers.customerid, Customers.companyname, 
       Orders.orderid, Orders.orderdate, 
       Products.productname, Products.unitprice
FROM Customers
INNER JOIN Orders
  ON Customers.customerid= Orders.customerid
INNER JOIN Orderdetails 
  ON Orders.orderid = Orderdetails.orderid
INNER JOIN Products 
  ON Orderdetails.productid = Products.productid

Agora, quero limitar a saída aos 3 pedidos mais recentes por cliente, mostrando apenas o produto mais caro do pedido. A saída ficaria mais ou menos assim (Edição: a tabela não está sendo exibida corretamente):

ID do cliente nome da empresa id do pedido data do pedido nome do produto preço unitário
ALFKI Alfreds Futterkiste 11011 1998-04-09 Flotemysost 22
ALFKI Alfreds Futterkiste 10952 1998-03-16 Chucrute Rössle 46
ALFKI Alfreds Futterkiste 10835 15/01/1998 Raclette Courdavault 55
ANATR Ana Trujillo Emparedados e sorvetes 10926 1998-03-04 Mussarela de Giovanni 35
ANATR Ana Trujillo Emparedados e sorvetes 10759 28/11/1997 Mascarpone Fabioli 32
ANATR Ana Trujillo Emparedados e sorvetes 10625 1997-08-08 Camembert Pierrot 34
ANTÔN Antonio Moreno Taqueria 10856 28/01/1998 Mudança 19
... ... ... ... ... ...

Tenho uma solução usando LATERAL()e uma subseleção, mas, especialmente em big data, quero usar isso, LATERAL()tem muitos custos e torna o processo bastante lento. Então, quero ter uma solução SEMLATERAL()

Outra solução que tenho tentado é usar, ROW_NUMBER()que é muito mais rápida:

Select * FROM( 
  SELECT Customers.customerid, Customers.companyname, 
         Orders.orderid, Orders.orderdate, 
         Products.productname, Products.unitprice,
         ROW_NUMBER() OVER (PARTITION BY Customers.customerid
                            ORDER BY o.orderdate desc, p.unitprice desc ) AS rn
        ...
 ) WHERE rn <= 3;

Agora, se o limite fosse 1, não haveria problema. Mas não consigo encontrar uma solução aceitável para um limite >= 2 para os pedidos, como expliquei acima. Tentei uma segunda solução ROW_NUMBER() OVER (PARTIONION BY Orders.orderid ...), mas para que isso funcionasse, precisaria de algum aninhamento. O problema com o aninhamento é que estou prestes a criar algo como um analisador sintático para uma aplicação. E aninhamento em excesso pode se tornar muito complicado e confuso (especialmente para fins de manutenção).

Então eu estava pensando em uma junção, existe uma solução SQL pura no Oracle para:

  • Junte 3 ou mais mesas.
  • Use um Limite >= 2 em uma tabela (B) no meio da Junção que tem várias junções com outra tabela a seguir.
  • Isso não usa LATERAL()
  • Não é necessário aninhamento?

Editar/Adicionado: A maneira que tenho usado LATERAL():

Como este é um banco de dados de exemplo, tive que reestruturar o LATERAL que estava usando. (Para o exemplo do Northwind, tenho que unir produtos em detalhes do pedido em pedidos, no meu banco de dados não preciso da etapa extra com uma tabela entre eles)

SELECT C.customerid, C.companyname, 
       O.orderid, O.orderdate, 
       P.productname, P.unitprice
FROM Customers C
INNER JOIN LATERAL( 
  SELECT Orders.orderid, Orders.orderdate FROM Orders 
  WHERE Orders.customerid = C.customerid 
  ORDER BY orderdate DESC FETCH FIRST 3 ROWS ONLY ) O 
  ON 1=1 
INNER JOIN LATERAL( 
  SELECT Products.unitprice, Products.productname FROM Orderdetails 
  INNER JOIN Products ON Products.productid = Orderdetails.productid 
  WHERE Orderdetails.orderid = O.orderid 
  ORDER BY Products.unitprice DESC FETCH FIRST 1 ROWS ONLY) P on 1=1

Usei ON 1=1porque a instrução on é obrigatória para o Oracle em uma instrução Join, mas já estou unindo dentro do LATERAL().

sql
  • 1 respostas
  • 66 Views
Martin Hope
jpo38
Asked: 2025-04-24 19:23:07 +0800 CST

O código C++ não consegue iterar a pasta do aplicativo ao implantar um aplicativo Qt no Android

  • 8

Estou migrando algum código do Qt 6.2.2 para o 6.9.0 no Android.

Tenho um código procurando arquivos .so na pasta do aplicativo (para possíveis plugins a serem carregados). Este código costumava iterar a pasta do aplicativo usando std::filesystemcódigo padrão. Não funciona mais. Consigo iterar a pasta HOME, mas não a pasta do aplicativo. Surpreendentemente QDir, consigo, mas meu código que faz isso é puramente C++/STL, não consigo usar Qt neste nível.

Algo mudou na estrutura do apk? Por que o STL não consegue ver a pasta do aplicativo? Existe alguma solução alternativa?

Aqui está um programa de exemplo muito simples:

#include <QApplication>
#include <QMainWindow>
#include <QLabel>
#include <QDebug>
#include <QDir>
#include <filesystem>
void listDirContent(QString path)
{
    {
        QDir dir(path);
        qDebug() << "Using Qt, " << path << ":";
        for (auto file : dir.entryList())
            qDebug() << file;
    }
    {
        std::filesystem::path std_path = path.toStdString();
        qDebug() << "using std, " << std_path.c_str() << ":";
        std::filesystem::directory_iterator itDir;
        std::filesystem::directory_iterator itEnd;
        std::filesystem::path Path;
        try
        {
            itDir = std::filesystem::directory_iterator(std_path);
            qDebug() << "Found files:";
            for (; itDir != itEnd; itDir++)
            {
                qDebug() << QString(itDir->path().c_str());
            }
            qDebug() << "end files";
        }
        catch (const std::exception& e)
        {
            qDebug() << "FAILED" << e.what();
        }
    }
}

int main( int argc, char* argv[] )
{
    QApplication app(argc, argv);
    QMainWindow wnd;
    wnd.setCentralWidget(new QLabel("Hello",&wnd));
    wnd.show();
    listDirContent(qApp->applicationDirPath());
    listDirContent(QDir::homePath());
    return app.exec();
}

Este programa produz:

D/default (18701): Using Qt,  "/data/app/org.qtproject.example.TestListDir-UzLzgFYV8gnNNAzUQkD1Lw==/base.apk!/lib/armeabi-v7a" :
D/default (18701): "armeabi-v7a"
D/default (18701): "libc++_shared.so"
D/default (18701): "libplugins_iconengines_qsvgicon_armeabi-v7a.so"
D/default (18701): "libplugins_imageformats_qgif_armeabi-v7a.so"
D/default (18701): "libplugins_imageformats_qico_armeabi-v7a.so"
D/default (18701): "libplugins_imageformats_qjpeg_armeabi-v7a.so"
D/default (18701): "libplugins_imageformats_qsvg_armeabi-v7a.so"
D/default (18701): "libplugins_platforms_qtforandroid_armeabi-v7a.so"
D/default (18701): "libplugins_styles_qandroidstyle_armeabi-v7a.so"
D/default (18701): "libQt6Core_armeabi-v7a.so"
D/default (18701): "libQt6Gui_armeabi-v7a.so"
D/default (18701): "libQt6Svg_armeabi-v7a.so"
D/default (18701): "libQt6Widgets_armeabi-v7a.so"
D/default (18701): "libTestListDir_armeabi-v7a.so"
D/default (18701): using std,  /data/app/org.qtproject.example.TestListDir-UzLzgFYV8gnNNAzUQkD1Lw==/base.apk!/lib/armeabi-v7a :
D/default (18701): FAILED filesystem error: in directory_iterator::directory_iterator(...): No such file or directory ["/data/app/org.qtproject.example.TestListDir-FvVxa-eHXbBc9Zpa2Q0uGQ==/base.apk!/lib/armeabi-v7a"]
D/default (18701): Using Qt,  "/data/user/0/org.qtproject.example.TestListDir/files" :
D/default (18701): "."
D/default (18701): ".."
D/default (18701): "profileInstalled"
D/default (18701): "profileinstaller_profileWrittenFor_lastUpdateTime.dat"
D/default (18701): using std,  /data/user/0/org.qtproject.example.TestListDir/files :
D/default (18701): Found files:
D/default (18701): /data/user/0/org.qtproject.example.TestListDir/files/profileinstaller_profileWrittenFor_lastUpdateTime.dat
D/default (18701): /data/user/0/org.qtproject.example.TestListDir/files/profileInstalled
D/default (18701): end files

Veja que std::filesystem não consegue iterar /data/app/org.qtproject.example.TestListDir-UzLzgFYV8gnNNAzUQkD1Lw==/base.apk!/lib/armeabi-v7aa pasta, ele relata que a pasta não existe, enquanto o Qt consegue iterar por ela.

Com o Qt 6.2.2, ele costumava listar os arquivos da pasta do aplicativo (o que era um pouco diferente, não havia "base.apk!" no caminho).

Relatei um bug no Qt: https://bugreports.qt.io/browse/QTBUG-136214

Alguém tem alguma ideia de como contornar esse problema? Como fazer com que o std::filestem consiga acessar a pasta do aplicativo?


Editar, std::filesystemé capaz de iterar /data/app/org.qtproject.example.TestListDir-UzLzgFYV8gnNNAzUQkD1Lw==, visto base.apkcomo um arquivo. Parece QDirsuportar um caso especial em que o nome do arquivo apk é seguido por !e é possível examiná-lo como se fosse, na verdade, uma pasta...

  • 1 respostas
  • 74 Views
Martin Hope
David
Asked: 2025-04-24 15:56:20 +0800 CST

Shiny torna reactive() assíncrono com ExtendedTask e mirai

  • 8

Tenho um aplicativo simples e brilhante onde um conjunto de dados é criado em uma reactive()chamada e depois plotado. Como a criação dos dados pode demorar um pouco, quero que ele seja chamado de assíncrono para que a sessão possa ser usada de outra forma. Para isso, quero usar shiny::ExtendedTask()with mirai.

Os documentos oficiais têm exemplos em que o task$invoke(...)é acionado por um botão (por exemplo, dentro de um shiny::observeEvent()), mas não há exemplos de como posso estruturar isso se minha função for acionada dentro de um reactive().

Observe que meu caso de uso real reutiliza os dados resultantes em alguns gráficos na página específica.

Aplicativo de sincronização MWE

O seguinte é um MWE para um aplicativo de bloqueio

library(shiny)
library(bslib)

create_data <- function(n) {
  Sys.sleep(2)
  data.frame(x = seq(n), y = rnorm(n))
}

ui <- page_fillable(
  card(
    card_header(span("To show reactive state, here is the current time ",
                     textOutput("current_time", inline = TRUE))),
    plotOutput("myplot")
  )
)

server <- function(input, output, session) {
  # note this reactive here should be put into an ExtendedTask
  data <- reactive({
    create_data(100)
  })
  
  output$myplot <- renderPlot({
    d <- data()
    plot(d$x, d$y)
  })

  
  # to show if the session is free: show current time
  output$current_time <- renderText({
    invalidateLater(1000, session)
    format(Sys.time(), "%H:%M:%S")
  })
  
}

shinyApp(ui, server)

Observe como a hora não é mostrada imediatamente porque a create_data()função bloqueia a sessão.

Tentativa de um aplicativo assíncrono

Para mostrar quando os eventos são acionados, movo o conteúdo para uma segunda página da barra de navegação. Portanto, espero que as tarefas sejam acionadas quando os dados forem necessários, pois a página é exibida (por exemplo, reactive()e não observe()o comportamento).

Minha tentativa malsucedida é então a seguinte (observe como eu aciono o task$invokecom um observe()este é o erro, mas não sei como eu acionaria isso com um reactive()ou de outra forma.

library(shiny)
library(bslib)
library(mirai)

create_data <- function(n) {
  Sys.sleep(2)
  data.frame(x = seq(n), y = rnorm(n))
}
# small helper function for logging
flog <- function(m) cat(sprintf("INFO [%s] | %s\n", format(Sys.time(), "%Y-%m-%d %H:%M:%OS3"), m))

ui <- page_navbar(
  nav_panel("Empty Default"),
  nav_panel(
    "Same as Before",
    card_header(span("To show reactive state, here is the current time ",
                     textOutput("current_time", inline = TRUE))),
    plotOutput("myplot")
  )
)

server <- function(input, output, session) {
  # create the task
  task <- ExtendedTask$new(function(...) mirai(fun(n = n), fun = create_data, ...))
  
  # this is the error here: the observe is not triggered by the rendered plot but by observe => fires immediately
  observe({
    flog("Task Invoke")
    task$invoke(n = 100)
    flog("Task Invoke Done")
  })
  
  output$myplot <- renderPlot({
    flog("Task Result")
    data <- task$result()
    flog("Task Result Done")
    
    plot(data$x, data$y)
  })
  
  
  # to show if the session is free: show current time
  output$current_time <- renderText({
    invalidateLater(1000, session)
    format(Sys.time(), "%H:%M:%S")
  })
}

shinyApp(ui, server)
  • 1 respostas
  • 57 Views
Prev
Próximo

Sidebar

Stats

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

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

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

    • 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

    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
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +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

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