htod
Enquanto D é compatível com binários de código C, ele não pode compilar código C nem arquivos cabeçalho C. Para que D se ligue com código C, as declarações C correspondentes que residem em arquivos cabeçalho C precisam ser convertidas para um módulo D. htod é uma ferramenta de migração para ajudar a convertar arquivos cabeçalho C.
htod é construído a partir do front end do compilador Digital Mars C e C++. Ele apenas trabalha como um compilador C ou C++ exceto que sua saída é um módulo D ao invés de um código objeto.
A macro __HTOD__ é predefinida e ajustada para 1, que é acessível para melhorar arquivos cabeçalho C para ter melhor saída D.
Download
Uso
htod cheader.h [dimport.d] [-cpp] [-hc] [-hi] [-hs] [-ht] { Interruptores compilador C }
onde:
- cheader.h
- Arquivos cabeçalho C ou C++ de entrada
- dimport.d
- Arquivo de saída do códifo fonte D (padrão é cheader.d)
- -cpp
- Indica um arquivo cabeçalho C++
- -hc
- Por padrão, htod irá inserir as declarações C e C++ em um arquivo no arquivo de saída pefixado por //C . -hc irá suprimir isso. Use somente se você está confiante de que htod está gerando o arquivo de saída correto (tal como se o arquivo cabeçalho foi modificado com __HTOD__).
- -hi
- Por padrão, htod irá representar um #include "file" com uma instrução import correspondente. O -hi fará as declarações no arquivo incluído serem convertidas para D tambéml. As declarações em todos os arquivos incluídos são análisadas de qualquer maneira. -hi é acessível ao substituir uma hierarquia de arquivos incluídos inteira com uma única importação D. Inclusões de sistema como #include <file> não são afetadas por -hi. Veja também -hs.
- -ht
- Por padrão, htod irá escrever tipos usando nomes de typedef como usando seus nomes. -ht fará os tipos subjacentes serem usados no lugar. Isso é muito útil para "perfurar" camadas de macros, typedefs, e #includes para achar o tipo subjacente.
- -hs
- Trabalha como -hi, exceto que inclusões de sistema também são migradas.
- Interruptores compilador C
- Interruptores do compilador C ou C++, tais como -D e -I como documentado por dmc.
Exemplo
O arquivo C test.h:
unsigned u;
#define MYINT int
void bar(int x, long y, long long z);
Traduzido com:
htod test.h
Produz o arquivo test.d:
/* Converted to D from test.h by htod */
module test;
//C unsigned u;
extern (C):
uint u;
//C #define MYINT int
//C void bar(int x, long y, long long z);
alias int MYINT;
void bar(int x, int y, long z);
As declarações C são prefixadas pela string "//C ".
Mapa de Tipos
Tipos C são mapeados como segue. Esses mapar estão corretos para Digital Mars C/C++, mas podem não estar corretos para seu compilador C. Tipos básicos D tem tamanhos fixos, enquanto tamanhos de tipos básicos C são definidos pela implementação.
Tipo C | Tipo D |
---|---|
void | void |
_Bool | bool |
wchar_t | wchar |
char | char |
signed char | byte |
unsigned char | ubyte |
short | short |
unsigned short | ushort |
int | int |
unsigned | uint |
long | int |
unsigned long | uint |
long long | long |
unsigned long long | ulong |
float | float |
double | double |
long double | real |
_Imaginary float | ifloat |
_Imaginary double | idouble |
_Imaginary long double | ireal |
_Complex float | cfloat |
_Complex double | cdouble |
_Complex long double | creal |
Limitações
There is no one to one correspondence of C declarations to D declarations. A review of the D module output will be necessary to ensure the right decisions are made. Furthermore:
- Sempre que prático, cabeçalhos C deveriam ser escritos usando typedef's e enum's ao invés de macros. htod tentará converter macros #define's simples para declarações alias e const. Mesmo assim, macros são totalmente expandidas antes de análise adicional.
- Nenhuma tentativa é feita para converter compilação condicional C em declarações D version ou static if.
- Nenhuma saída é gerada para seções de compilação condicional falsas.
- htod só converte declarações, ele não converte código C.
- Declarações com ligação C++ não podem ser convertidas. Uma interface C deve serfeita para qualquer código C++.
- Extensões da linguagem C presentes no arquivo .h podem não ser reconhecidas.
- Pragmas não são traduzidos.
- Os nomes de marcadores são assumidos para não colidir com nomes no espaço de nomes regular.
- Qualquer dado de caracter que não é ASCII precisará ser convertido como necessário para UTF.
- O tipo C char é assumido para mapear para o tipo D char. Porém, estes deveriam ser examinados individualmente para ver se eles deveriam ser traduzidos para os tipos byte ou ubyte. Se o tipo C char tem sinal ou não é definido pela implementação. O tipo D char não tem sinal.
- Membros nomeados de enum C não são inseridos no escopo envolvendo-os como eles são em C.
- Módulos D estão cada um em seu próprio espaço de nomes, mas arquivos cabeçalho C estão todos no mesmo espaço de nomes global. Isso significa que referências D para nomes definidos em outros módulos podem precisar ser qualificadas.
Bugs
- Qualquer coisa diferente do alinhamento padrão de membros de estrutura não é esclarecido.
- Nenhuma versão para Linux.