Revisar o velho e aprender o novo, você pode ficar molhado
Primeiro de tudo, lembre -se deste Manual Online de V8 - http://izs.me/v8-docs/main.html.
Lembre -se do arquivo Último edifício.gyp?
A cópia do código é a seguinte:
{
"Alvos": [
{
"Target_name": "addon",
"Fontes": ["addon.cc"]
}
]
}
Assim, aprenda com um exemplo e aprenda com ele. Se você tiver mais arquivos .cc, será assim:
"Fontes": ["addon.cc", "myexample.cc"]
A última vez que separamos as duas etapas e, de fato, a configuração e a compilação podem ser montadas:
$ Node-GYP Configurar Build
Você terminou de revisar? sem? !
OK, então vamos continuar.
Índice
Parâmetros de função
Agora finalmente vamos falar sobre parâmetros.
Vamos imaginar que existe uma função add (a, b) que representa a adição de A e B para retornar o resultado, então escreva a estrutura externa da função primeiro:
A cópia do código é a seguinte:
#include <node.h>
usando namespace v8;
Handle <Value> Adicionar (Argumentos e Args)
{
Escopo de manipulação;
// ... Venha de novo!
}
Argumentos
Este é o parâmetro da função. Vamos dar uma olhada na referência manual oficial do V8 primeiro.
• Int comprimento () const
• Operador local <Value> [] (int i) const
Não nos importamos com os outros, esses dois são muito importantes! Um representa o número de parâmetros passados na função, e o outro são os colchetes que acessam o enésimo parâmetro através do índice subscrito.
Assim, como para os requisitos acima, podemos entender aproximadamente que o args.length () é 2, args [0] representa A e Args [1] representa b. E devemos julgar que o tipo desses dois números deve ser o número.
Não tenho certeza, o operador de índice no suporte retorna o resultado de um <Value> local, que é a classe base de todos os tipos de node.js. Portanto, se os parâmetros passados forem do tipo variável, devemos julgar quais parâmetros são. Isso está relacionado a algumas funções desse tipo de valor.
• Isarray ()
• IsBoolean ()
• ISDATE ()
• isfunção ()
• ISINT32 ()
• IsnativeError ()
• isnull ()
• isNumber ()
• IsRegexp ()
• Isstring ()
• ...
Não vou listar todos eles, leia o resto sozinho. 。:. ゚ (*´∀`) ノ゚ .:。
ThrowException
Esta é uma função que usaremos mais tarde. Especificamente, ele pode ser encontrado na documentação V8.
Como o nome sugere, ele está lançando um erro. Depois de executar esta declaração, é equivalente a executar uma instrução tiro () no arquivo node.js local. Por exemplo:
ThrowException (exceção :: typeError (string :: new ("número errado de argumentos")));
É equivalente a executar um node.js:
lançar um novo TypeError ("Número errado de argumentos");
Indefinido()
Esta função também está no documento.
Especificamente, é um valor nulo, porque algumas funções não precisam retornar nenhum valor específico ou não retornar um valor. Neste momento, a Undefined () precisa ser usada.
Agir!
Depois de entender os pontos acima, acredito que você poderá escrever a lógica de A + B em breve. Vou copiar o código do manual oficial do Node.js e lê -lo para você. Será feito:
A cópia do código é a seguinte:
#include <node.h>
usando namespace v8;
Handle <Value> Adicionar (Argumentos e Args)
{
Escopo de manipulação;
// significa que mais de 2 parâmetros podem ser transmitidos, mas na verdade usamos apenas os dois primeiros
if (args.length () <2)
{
// lançar um erro
ThrowException (exceção :: typeError (string :: new ("número errado de argumentos")));
// retorna valor vazio
retorno scope.close (undefined ());
}
// Se um dos dois primeiros parâmetros não for um número
if (! args [0]-> isnumber () ||! args [1]-> isNumber ())
{
// joga um erro e retorne um valor nulo
ThrowException (exceção :: typeError (string :: new ("argumentos errados"));
retorno scope.close (undefined ());
}
// Para detalhes, consulte a documentação V8
// http://izs.me/v8-docs/classv8_1_1value.html#a6eac2b07dced58f1761bbfd53bf0e366)
// Função `numberValue`
Local <número> num = número :: new (args [0]-> numberValue () + args [1]-> numberValue ());
retorno scope.close (num);
}
A função está feita!
Por fim, escreva a função de exportação no final e tudo bem.
A cópia do código é a seguinte:
Void Init (Handle <just> Exporta)
{
exports-> set (string :: newsymbol ("add"),
FunctionTemplate :: new (add)-> getFunction ());
}
Node_module (addon, init)
Depois de compilar, podemos usá -lo assim:
A cópia do código é a seguinte: var addon = requer ('./ build/release/addon');
console.log (addon.add (1, 1) + "b");
Você verá um 2B! ✧。٩ (ᗜ) و✧*.
Função de retorno de chamada
No capítulo anterior, falamos apenas sobre o Hello World. Neste capítulo, o mestre da avó o descobriu com consciência e escreveu uma função de retorno de chamada.
Para a convenção, vamos escrever uma estrutura primeiro:
A cópia do código é a seguinte:
#include <node.h>
usando namespace v8;
Handle <Value> RuCallback (Argumentos e Args)
{
Escopo de manipulação;
// ... estrezle racha estrenda estrezura estrezle racha estrezina
retorno scope.close (undefined ());
}
Então decidimos como é usado assim:
func (função (msg) {
console.log (msg);
});
Ou seja, ele passará um parâmetro para a função de retorno de chamada, imaginamos que é uma string e, em seguida, podemos consolar.log () para vê -la.
Primeiro você precisa de uma série de string
Sem mais delongas, vamos alimentá -lo primeiro. (√ ζ ε :)
Mas temos que criar essa sequência de tipos genéricos porque o código node.js é fraco.
Local <Value> :: new (String :: new ("Hello World"));
O que? Você me pergunta o que é local <Value>?
Então falarei um pouco sobre isso, consulte os documentos de referência daqui e do V8.
Como mostra a documentação, na verdade herda local <t> Handle <t>, e lembro que o capítulo anterior já havia falado sobre o Handle <T>.
Então aqui está o local.
Existem dois tipos de alça, alça local e alça persistente, que são locais <T>: Handle <t> e persistente <T>: Handle <T>. Não há diferença entre o primeiro e a alça <t> e os dois ciclos de sobrevivência estão dentro do escopo. O ciclo de vida deste último é separado do escopo, você precisa chamar manualmente persistente :: Dispor para encerrar seu ciclo de vida. Em outras palavras, o identificador local é equivalente a alocar objetos na pilha no C ++ `e o identificador persistente é equivalente a objetos de alocação de C ++ na pilha.
Então você precisa de uma série de tabela de parâmetros
Como obter parâmetros da linha de comando após ligar para C/C ++ na linha de comando do terminal?
A cópia do código é a seguinte:
#include <stdio.h>
void main (int argc, char* argv [])
{
// ...
}
A propósito, o ARGC aqui é o número de parâmetros da linha de comando e o argv [] são os vários parâmetros. Então o V8 também usa um método semelhante para chamar a função de retorno de chamada do Node.js:
A cópia do código é a seguinte: V8Export local <Value> v8 :: function :: Call (manipulador <ject> recv,
int argc,
Manuseio <Value> argv []
);
~~ Qaq está preso na alça <ject> recv! ! ! Continue escrevendo amanhã. ~~
Bem, o novo dia começa e eu sinto que estou cheio de força. (∩^o^) ⊃━☆゚.*・。。
Depois de verifiquei em muitos aspectos (segmentfault, Stackoverflow e um grupo QQ), finalmente resolvi o significado dos três parâmetros da função acima.
Não vou falar sobre os dois últimos parâmetros, um é o número de parâmetros e o outro é uma matriz de parâmetros. Quanto ao primeiro parâmetro Handle <ject> RECV, a explicação do StackOverflow Brother é a seguinte:
É o mesmo aplicado em JS. Em JS, você faz
A cópia do código é a seguinte:
var context = ...;
cb.Apply (contexto, [... args ...]);
O objeto passou como o primeiro argumento se torna isso dentro do escopo da função. Mais documentação no MDN. Se você não conhece bem o JS, pode ler mais sobre o JS: http://unschooled.org/2012/03/undestanding-javascript-this/
- Extraído do Stackoverflow
Em suma, sua função é especificar esse ponteiro para a função chamada. O uso desta chamada é semelhante a Bind (), Call () e Apply () em JavaScript.
Portanto, o que precisamos fazer é criar primeiro a tabela de parâmetros e depois passar nesta função de chamada para sua execução.
O primeiro passo é exibir a função de conversão, porque era originalmente um tipo de objeto:
Local <function> cb = local <ctunction> :: elenco (args [0]);
A segunda etapa é criar uma tabela de parâmetros (matriz):
Local <Value> argv [argc] = {local <Value> :: new (string :: new ("hello world"))};
A chamada final para a série de funções
Ligue para CB e passe os parâmetros em:
cb-> ligue (context :: getCurrent ()-> global (), 1, argv);
O primeiro parâmetro aqui contexto :: getCurrent ()-> global () significa obter essa função do contexto global; O segundo parâmetro é o número na tabela de parâmetros (afinal, embora a matriz de node.js tenha um atributo de comprimento, o sistema realmente não conhece o comprimento da matriz em C ++ e você precisa passar em um número para explicar o comprimento da matriz); O último parâmetro é a tabela de parâmetros que acabamos de estabelecer.
Série de arquivos finais do capítulo final
Acredito que todos já estão familiarizados com esta etapa, apenas escreva a função, depois a coloque na função de exportação e finalmente a declare.
Vou apenas postar o código ou apenas ir ao documento Node.js para lê -lo.
A cópia do código é a seguinte:
#include <node.h>
usando namespace v8;
Handle <Value> RuCallback (Argumentos e Args)
{
Escopo de manipulação;
Local <function> cb = local <ctunction> :: elenco (args [0]);
const não assinado argc = 1;
Local <Value> argv [argc] = {local <Value> :: new (string :: new ("hello world"))};
cb-> ligue (context :: getCurrent ()-> global (), argc, argv);
retorno scope.close (undefined ());
}
Void init (manipulação <just> exporta, handle <ject> módulo)
{
Módulo-> set (String :: Newsymbol ("Exportações"),
FunctionTemplate :: new (runCallback)-> getFunction ());
}
Node_module (addon, init)
Bom trabalho! Vamos fazer os últimos passos. Quanto a chamar essa função em JS, eu já mencionei isso antes.
Extra
Bem, sinto que minhas anotações de estudo estão se tornando cada vez mais irrestritas e quero quebrá -las ~
Vamos parar aqui hoje. Durante o processo de redação de notas de estudo, aumentei minha postura novamente, como o significado do parâmetro da função de chamada.
Se você acha que esta série de notas de estudo é útil para você, venha e divirta -se comigo ~ σ> (〃 ° ω ° 〃) ♡ →