Uma armadilha de n há muito tempo - usando o Node.js para reconstruir o juiz on -line do NBUT, incluindo o lado da avaliação, também precisa ser reconstruído. (Quanto a quando for concluído, não se importe, (/д ′)/~
Em suma, o que vamos fazer agora é usar C/C ++ para implementar os módulos Node.js.
Preparação
Se você quiser fazer bem as coisas, primeiro deve agir como um gângster e aprimorar suas ferramentas.
Node-GYP
Primeiro você precisa de um módulo Node-GYP.
Em qualquer canto, execute:
A cópia do código é a seguinte:
$ npm install node -gyp -g
Depois de uma série de Blahblahs, você o instalou.
Python
Então você precisa ter um ambiente Python.
Vá para o site oficial e obtenha um.
NOTA: De acordo com a tela GitHub do Node-GYP, certifique-se de garantir que sua versão Python esteja entre 2.5.0 e 3.0.0.
Ambiente de compilação
Bem, estou apenas preguiçoso e não escrevo em detalhes. Por favor, vá para o Node-GYP para ver as necessidades do compilador. E faça um barulho.
começando
Vou falar sobre a introdução ao site oficial Hello World.
Olá mundo
Prepare um arquivo C ++, por exemplo, é chamado ~~ sb.cc ~~ hello.cc.
Em seguida, daremos um passo a passo, primeiro criaremos o arquivo de cabeçalho e definiremos o espaço para nome:
A cópia do código é a seguinte:
#include <node.h>
#include <v8.h>
usando namespace v8;
Funções principais
Em seguida, escrevemos uma função cujo valor de retorno é o identificador <Value>.
A cópia do código é a seguinte:
Handle <Value> Olá (Argumentos e Args)
{
// ... estava com fome de ser escrito
}
Então vou analisar essas coisas aproximadamente:
Manuseio <Value>
Você deve ser honesto na vida. Declaro antecipadamente que me refiro a partir daqui (@fool).
V8 usa o tipo de alça para hospedar objetos JavaScript. Semelhante ao Std :: SharedPointer do C ++, as atribuições entre os tipos de alça são referências de objeto diretamente passadas, mas a diferença é que o V8 usa seu próprio GC para gerenciar o ciclo de vida do objeto, em vez da contagem de referência comumente usada por ponteiros inteligentes.
Os tipos JavaScript possuem tipos personalizados correspondentes em C ++, como string, número inteiro, objeto, data, matriz etc., e permanecem estritamente com a relação de herança no JavaScript. Ao usar esses tipos no C ++, você deve usar a HOLLE Hosting para usar o GC para gerenciar seus ciclos de vida sem usar pilhas e montes nativos.
Esse valor chamado, que pode ser visto nas várias relações de herança no arquivo de cabeçalho v8.h do mecanismo V8, é na verdade a classe base de vários objetos no JavaScript.
Depois de entender isso, podemos entender aproximadamente o significado da declaração de função acima, o que significa que escrevemos uma função Hello, que retorna um valor de um tipo incerto.
NOTA: Só podemos retornar tipos específicos, a saber, string, número inteiro, etc. em Hanking Hosting.
Argumentos
Este é o parâmetro a passar nesta função. Todos sabemos que no Node.js, o número de parâmetros é aleatório. Quando esses parâmetros são passados para C ++, eles são convertidos em um objeto de tipo de argumentos.
Vamos falar sobre o uso específico mais tarde. Aqui só precisamos entender o que é isso. (Para mantê -lo em segredo? Porque os exemplos no documento oficial do Node.js são discutidos separadamente. Estou falando sobre o primeiro exemplo do Hello World (´థ౪థ) σ
Adicione tijolos e azulejos
Em seguida, começamos a contribuir. Apenas as frases mais simples:
A cópia do código é a seguinte:
Handle <Value> Olá (Argumentos e Args)
{
Escopo de manipulação;
return scope.close (string :: new ("mundo"));
}
O que essas duas frases significam? O significado geral é devolver uma string "mundo" em node.js.
Handlescope
A mesma referência é daqui.
O ciclo de vida da alça é diferente do dos ponteiros inteligentes C ++. Ele não sobrevive dentro do escopo da semântica C ++ (ou seja, a parte cercada por {}), mas precisa ser especificada manualmente através do HandleScope. O HandleScope só pode ser alocado na pilha. Depois que o objeto HandleScope é declarado, a alça criada posteriormente é gerenciada pelo HandlesCope. Depois que o objeto Handlescope é destruído, o identificador gerenciado por ele será determinado pelo GC.
Portanto, temos que declarar esse escopo quando precisamos gerenciar seu ciclo de vida. Ok, então por que nosso código não será escrito assim?
A cópia do código é a seguinte:
Handle <Value> Olá (Argumentos e Args)
{
Escopo de manipulação;
retornar string :: new ("mundo");
}
Porque quando a função retornar, o escopo será destruído e as alças que ele gerenciarão serão recicladas, para que essa string se torne sem sentido.
Então, o V8 teve uma ideia mágica - a função HandleScope :: Close (Handle <T> Value)! O objetivo desta função é fechar o escopo e entregar os parâmetros no interior do gerenciamento de escopo anterior, ou seja, o escopo antes de inserir essa função.
Portanto, temos o código de código anterior.close (string :: new ("mundo"));.
String :: novo
A classe String corresponde à classe String nativa em Node.js. Herdado da classe Value. Da mesma forma, existem:
•Variedade
• Inteiro
• Booleano
•Objeto
•Data
•Número
•Função
• ...
Algumas dessas coisas são herdadas do valor, enquanto outras são herdadas do secundário. Não faremos muita pesquisa aqui. Você pode olhar para o código V8 (pelo menos o arquivo de cabeçalho) ou olhar para este manual.
E quanto a isso novo? Você pode ver aqui. É para criar um novo objeto String.
Neste ponto, terminamos a análise dessa função principal.
Exportar objetos
Vamos revisá -lo. Se estiver escrito no Node.js, como exportamos funções ou objetos?
A cópia do código é a seguinte:
exports.hello = function () {}
Então, como podemos fazer isso no C ++?
Inicialize a função
Primeiro, vamos escrever uma função de inicialização:
A cópia do código é a seguinte:
Void Init (Handle <just> Exporta)
{
// ... Estou com fome de escrever sobre sua irmã! #゚ Å ゚) ⊂ち☆)) ゚ д ゚) ・∵
}
Esta é uma bunda de tartaruga! Não importa se o nome da função ou algo assim, mas o parâmetro passado deve ser um identificador <ject>, o que significa que exportaremos as coisas deste produto abaixo.
Então, escrevemos a coisa exportada aqui:
A cópia do código é a seguinte:
Void Init (Handle <just> Exporta)
{
exports-> set (string :: Newsymbol ("hello"),
FunctionTemplate :: new (hello)-> getFunction ());
}
O significado geral é adicionar um campo chamado Hello a este objeto de exportações, e a coisa correspondente é uma função, e essa função é nossa função Dear Hello.
Para escrever um ponto simples no código pseudo:
A cópia do código é a seguinte:
Void Init (Handle <just> Exporta)
{
exports.set ("hello, função hello);
}
O trabalho está feito!
(Sua irmã terminou! Cale a boca ('д'⊂☡☆)) д')
Exportação verdadeira
Esta é a última etapa, e finalmente declararemos que esta é a entrada da exportação, por isso adicionamos essa linha no final do código:
Node_module (Olá, init)
Você tomou uma NI? ! O que é isso?
Não se preocupe, este Node_module é uma macro, o que significa que usamos a função de inicialização iniciante para exportar as coisas a serem exportadas para a Hello. Então, de onde vem esse olá?
Vem do nome do arquivo! Sim, sim, ele vem do nome do arquivo. Você não precisa declarar com antecedência e não precisa se preocupar em não poder usá -lo. Em suma, qual é o nome do seu arquivo binário final compilado? Você preencherá o olá aqui e, é claro, precisa remover o nome do sufixo.
Veja a documentação oficial para obter detalhes.
Observe que todos os nó adicionam deve exportar uma função de inicialização:
A cópia do código é a seguinte:
void Initialize (manipulação <ject> exports);
Node_module (module_name, inicializar)
Não há semi-colon após o node_module, pois não é uma função (consulte Node.h).
O Module_Name precisa corresponder ao nome do arquivo do binário final (menos o sufixo .Node).
Compilar (๑ • ́ ₃ ̀๑ ̀๑)
Vamos lá, vamos compilar juntos!
Vamos criar um novo arquivo de arquivo semelhante ao makefile - binding.gyp.
E adicione o código como este:
A cópia do código é a seguinte:
{
"Alvos": [
{
"Target_name": "Hello",
"Fontes": ["hello.cc"]
}
]
}
Por que escrever isso? Você pode consultar a documentação oficial do Node-GYP.
configure
Depois que o arquivo estiver pronto, precisamos executar este comando neste diretório:
A cópia do código é a seguinte:
$ Node-GYP Configurar
Se estiver tudo bem, um diretório de compilação deve ser gerado e, em seguida, existem arquivos relacionados, talvez m $ visual studio vcxproj, etc., ou talvez makefile, dependendo da plataforma.
construir
Depois que o Makefile é gerado, começamos a construir e compilar:
$ Node-GYP Build
Somente quando tudo for compilado, será considerado que a tarefa real é concluída! Se você não acredita, vá e verifique o diretório de construção/liberação. Existe um arquivo hello.node abaixo? É isso mesmo, este é o sabonete que o C ++ deseja pegar para o Node.js mais tarde!
Vamos pegar o básico! Nó (✿゚゚) ノ C ++
Criamos um novo arquivo jianfeizao.js no diretório agora:
A cópia do código é a seguinte:
var addon = requer ("./ build/release/hello");
console.log (addon.hello ());
Veja ou não! Veja ou não! Sair! O resultado de Node.js e C ++ recebendo o básico! Este addon.hello () é o identificador <Value> hello (const Argumments & Args) que escrevemos no código C ++ antes, e agora já emitimos o valor que ele retorna.
Tome um banho e vá para a cama, e a próxima seção é mais profunda
Está ficando tarde, então vou acabar escrevendo hoje. Até agora, todos podem criar a extensão mais básica do Hello World C ++. Na próxima vez que escrever, não sei quando será a próxima vez.
(Ei, ei, como o mestre pode ser tão irresponsável! (O ゚ロ?) ┌┛σ (ノ ´ω`) ノ