


Alterar um wrapper gerenciado e sua biblioteca nativa sem quebrar a ABI
Use ao editar um wrapper gerenciado multiplataforma sobre uma biblioteca C nativa. Segue cada mudança pelas camadas, compila binários nativos do código-fonte em vez de downloads antigos, mantém a ABI pública estável, trata a posse de ponteiros e as threads e não pula testes que falham.
Para usar estas regras de IA
## Seguir cada mudança do wrapper gerenciado até o código nativo
Trate a biblioteca como um sistema em camadas: wrapper gerenciado, declarações de interoperabilidade, API estável compatível com C e implementação nativa.
- Valide as entradas públicas no wrapper gerenciado.
- Mantenha a ponte compatível com C pequena e previsível; ela deve traduzir e encaminhar, não duplicar políticas.
- Preserve a correspondência exata entre declarações gerenciadas, símbolos C exportados, tipos de parâmetros, tipos de retorno e implementações nativas.
- Antes de editar o código, determine qual camada é responsável por cada regra de validação, alocação, conversão de erro e transição de ciclo de vida.
- Acompanhe uma alteração por todas as camadas afetadas, em vez de corrigir apenas o primeiro erro de compilação.
Uma alteração que compila na camada gerenciada ainda pode falhar em tempo de execução quando o binário nativo não contém o novo símbolo ou usa uma assinatura diferente.
## Escolher binários nativos pré-compilados ou compilados da fonte conforme a mudança
Os binários nativos devem existir antes da compilação do wrapper gerenciado, mas a origem correta deles depende do que foi alterado.
- Para trabalho exclusivamente gerenciado, use os artefatos nativos pré-compilados aprovados pelo repositório para o marco publicado atual.
- Para alterações na implementação nativa, API C, dependências, submódulo, versão ou marco, compile os binários nativos a partir do código-fonte para a plataforma e arquitetura de destino.
- Depois de qualquer alteração que afete o lado nativo, é proibido baixar os binários pré-compilados atuais até que essas alterações tenham sido publicadas na origem dos artefatos.
- Se a compilação nativa a partir do código-fonte falhar, diagnostique os pré-requisitos de ferramentas, dependências, caminhos ou rede. Nunca recorra a downloads obsoletos apenas para fazer a compilação gerenciada passar.
- Limpe os caches da plataforma quando eles puderem reter um módulo nativo antigo e produzir resultados de teste falsos.
Usar binários nativos obsoletos após uma alteração de API pode produzir uma compilação silenciosamente incorreta, seguida por falhas de ponto de entrada ausente em tempo de execução.
## Regenerar os bindings em vez de editá-los e manter a ABI estável
Não edite manualmente bindings gerados, documentação gerada, páginas de versão renderizadas nem qualquer outra saída declarada como gerada. Altere a fonte editável e execute o gerador do repositório após qualquer alteração na API C.
Mantenha estável a interface binária de aplicação:
- Adicione sobrecargas, métodos ou tipos em vez de alterar assinaturas existentes.
- Não remova APIs públicas nem altere seus tipos de retorno.
- Prefira sobrecargas a novos parâmetros padrão, pois parâmetros padrão podem alterar a compatibilidade binária.
- Marque uma API como obsoleta em vez de removê-la e forneça orientações de migração práticas.
- Mantenha as convenções de nomenclatura e parâmetros consistentes com as APIs públicas próximas.
- Gere novamente os bindings e verifique a diferença resultante antes de compilar.
Quando a documentação tiver páginas geradas e fontes auxiliares editáveis, altere apenas a fonte indicada e renderize a saída novamente.
## Classificar a posse dos ponteiros nativos e não compartilhar objetos mutáveis entre threads
Classifique cada ponteiro nativo antes de escrever um wrapper:
- Um parâmetro emprestado não transfere propriedade.
- Um objeto nativo de propriedade manual exige o caminho de descarte nativo do wrapper.
- Um objeto com contagem de referências deve usar o contrato de contagem de referências do wrapper.
Associe o comportamento de falha à camada. A API compatível com C retorna um ponteiro nulo ou `false`; uma factory gerenciada retorna `null`; um construtor gerenciado lança uma exceção quando não consegue estabelecer um objeto válido.
Algumas operações nativas podem retornar a mesma instância que receberam. Compare as identidades antes de descartar a origem; caso contrário, o valor retornado poderá referenciar um objeto que já foi liberado.
Não compartilhe objetos nativos mutáveis entre threads, a menos que o contrato nativo permita isso explicitamente. Dê a cada thread seu próprio estado mutável; compartilhe apenas objetos documentados como imutáveis e seguros para threads.
Nunca passe um ponteiro gerenciado temporariamente fixado para código nativo que possa retê-lo além do escopo de fixação. Use um handle fixado com ciclo de vida explícito ou aloque memória não gerenciada. Violar esta regra permite que o coletor de lixo mova a memória enquanto o código nativo ainda mantém o endereço antigo.
## Usar branches de recurso no repositório principal e no submódulo nativo
Crie uma branch de recurso antes de fazer commits. Nunca faça commit diretamente em branches protegidas.
Aplique a mesma regra de modo independente a um submódulo nativo ou repositório aninhado: ele tem seu próprio estado de branches, branches protegidas, commits e caminho de revisão.
1. Crie uma branch de recurso focada no repositório principal.
2. Se o repositório nativo aninhado for alterado, crie nele uma branch de recurso antes de editar ou fazer commit.
3. Mantenha todos os commits nas branches de recurso correspondentes.
4. Envie as alterações para revisão pelo fluxo de pull request aprovado pelo repositório.
5. Confirme que o repositório principal registra a revisão nativa pretendida e já revisada.
Não altere diretórios nativos gerenciados pelo projeto de origem fora da superfície de adaptação ou extensão declarada pelo repositório.
## Testar com os binários nativos corretos sem pular falhas
Uma compilação bem-sucedida não representa a conclusão. Execute os testes gerenciados relevantes usando binários nativos produzidos pelo caminho de bootstrap correto.
- Os testes devem passar antes de declarar a conclusão.
- Não ignore um teste com falha nem introduza uma exceção de omissão para contornar uma regressão.
- Uma omissão só é aceitável por uma limitação comprovada de hardware ou plataforma, como a ausência de tela, indisponibilidade de dispositivo gráfico ou falta de suporte da plataforma ao recurso.
- Gere novamente os bindings antes dos testes quando a API C tiver sido alterada.
- Limpe artefatos nativos web ou de plataforma armazenados em cache antes de validar alterações de versão.
- Verifique plataformas e arquiteturas representativas em trabalhos que afetem o lado nativo.
Escreva testes que falhem quando a propriedade, o tratamento de nulos, os símbolos exportados, a ABI, o escopo das threads ou o descarte estiverem incorretos. Inclua testes de paridade e benchmarks para alterações de desempenho quando o comportamento exato ou o benefício ainda não estiver comprovado.
## Encontrar erros entre camadas pelo formato da falha
Estabeleça uma linha de base comprovadamente válida, altere uma variável por vez, registre cada resultado e trate as diferenças entre plataformas como evidência. Se uma alteração piorar o estado, reverta-a antes de testar outra hipótese.
Use o formato da falha para escolher o primeiro limite a inspecionar:
- A ausência de um tipo gerenciado sugere que os bindings não foram gerados novamente ou incluídos.
- Um símbolo nativo não resolvido sugere divergência entre a declaração C e a implementação.
- Um ponto de entrada ausente em tempo de execução sugere fortemente binários nativos obsoletos ou uma exportação incompatível.
- Uma violação de acesso sugere corrupção de propriedade, descarte, fixação ou assinatura.
- Uma falha de referência nula após uma chamada de factory sugere que a camada nativa retornou uma falha e o chamador a ignorou.
- Falhas aleatórias entre threads sugerem que objetos nativos mutáveis foram compartilhados.
Antes de concluir, inspecione as diferenças geradas, compile o código nativo quando necessário, compile o wrapper gerenciado, execute os testes e verifique a matriz de plataformas afetada. Informe a origem e a arquitetura exatas usadas no bootstrap. Não declare sucesso quando os testes falharem, quando compilações nativas obrigatórias tiverem sido substituídas por downloads ou quando a verificação de plataformas permanecer incompleta.
