Esta es una implementación ENet independiente con un protocolo modificado para C, C++, C# y otros lenguajes.
Características:
Por favor, lea los errores comunes para tener una idea de qué puede salir mal.
Para construir la biblioteca nativa se requiere el software apropiado:
Para plataformas de escritorio CMake con GNU Make o Visual Studio.
Para plataformas móviles NDK para Android y Xcode para iOS. Asegúrese de que todas las bibliotecas compiladas estén asignadas a las plataformas y arquitecturas de CPU adecuadas.
Para crear la biblioteca para Nintendo Switch, sigue esta guía.
Se puede crear un ensamblado administrado utilizando cualquier plataforma de compilación disponible que admita C# 3.0 o superior.
Puede obtener bibliotecas compiladas desde la sección de lanzamiento o desde NuGet:
ENet-CSharp
contiene un ensamblado compilado con bibliotecas nativas para el entorno .NET (.NET Standard 2.1).
ENet-Unity
contiene scripts con bibliotecas nativas para Unity.
Se recomienda encarecidamente eliminar una carpeta con archivos binarios en lugar de reemplazarla para actualizar.
Estos paquetes se proporcionan únicamente para plataformas tradicionales: Windows, Linux y macOS (x64).
Versiones de sistema operativo compatibles:
Antes de comenzar a trabajar, la biblioteca debe inicializarse usando ENet.Library.Initialize();
función.
Una vez finalizado el trabajo, desinicialice la biblioteca utilizando ENet.Library.Deinitialize();
función.
using ( Host server = new Host ( ) ) {
Address address = new Address ( ) ;
address . Port = port ;
server . Create ( address , maxClients ) ;
Event netEvent ;
while ( ! Console . KeyAvailable ) {
bool polled = false ;
while ( ! polled ) {
if ( server . CheckEvents ( out netEvent ) <= 0 ) {
if ( server . Service ( 15 , out netEvent ) <= 0 )
break ;
polled = true ;
}
switch ( netEvent . Type ) {
case EventType . None :
break ;
case EventType . Connect :
Console . WriteLine ( "Client connected - ID: " + netEvent . Peer . ID + ", IP: " + netEvent . Peer . IP ) ;
break ;
case EventType . Disconnect :
Console . WriteLine ( "Client disconnected - ID: " + netEvent . Peer . ID + ", IP: " + netEvent . Peer . IP ) ;
break ;
case EventType . Timeout :
Console . WriteLine ( "Client timeout - ID: " + netEvent . Peer . ID + ", IP: " + netEvent . Peer . IP ) ;
break ;
case EventType . Receive :
Console . WriteLine ( "Packet received from - ID: " + netEvent . Peer . ID + ", IP: " + netEvent . Peer . IP + ", Channel ID: " + netEvent . ChannelID + ", Data length: " + netEvent . Packet . Length ) ;
netEvent . Packet . Dispose ( ) ;
break ;
}
}
}
server . Flush ( ) ;
}
using ( Host client = new Host ( ) ) {
Address address = new Address ( ) ;
address . SetHost ( ip ) ;
address . Port = port ;
client . Create ( ) ;
Peer peer = client . Connect ( address ) ;
Event netEvent ;
while ( ! Console . KeyAvailable ) {
bool polled = false ;
while ( ! polled ) {
if ( client . CheckEvents ( out netEvent ) <= 0 ) {
if ( client . Service ( 15 , out netEvent ) <= 0 )
break ;
polled = true ;
}
switch ( netEvent . Type ) {
case EventType . None :
break ;
case EventType . Connect :
Console . WriteLine ( "Client connected to server" ) ;
break ;
case EventType . Disconnect :
Console . WriteLine ( "Client disconnected from server" ) ;
break ;
case EventType . Timeout :
Console . WriteLine ( "Client connection timeout" ) ;
break ;
case EventType . Receive :
Console . WriteLine ( "Packet received from server - Channel ID: " + netEvent . ChannelID + ", Data length: " + netEvent . Packet . Length ) ;
netEvent . Packet . Dispose ( ) ;
break ;
}
}
}
client . Flush ( ) ;
}
Packet packet = default ( Packet ) ;
byte [ ] data = new byte [ 64 ] ;
packet . Create ( data ) ;
peer . Send ( channelID , ref packet ) ;
byte [ ] buffer = new byte [ 1024 ] ;
netEvent . Packet . CopyTo ( buffer ) ;
AllocCallback OnMemoryAllocate = ( size ) => {
return Marshal . AllocHGlobal ( size ) ;
} ;
FreeCallback OnMemoryFree = ( memory ) => {
Marshal . FreeHGlobal ( memory ) ;
} ;
NoMemoryCallback OnNoMemory = ( ) => {
throw new OutOfMemoryException ( ) ;
} ;
Callbacks callbacks = new Callbacks ( OnMemoryAllocate , OnMemoryFree , OnNoMemory ) ;
if ( ENet . Library . Initialize ( callbacks ) )
Console . WriteLine ( "ENet successfully initialized using a custom memory allocator" ) ;
El uso es casi el mismo que en el entorno .NET, excepto que las funciones de la consola deben reemplazarse con funciones proporcionadas por Unity. Si se llamará a Host.Service()
en un bucle de juego, asegúrese de que el parámetro de tiempo de espera esté establecido en 0, lo que significa que no es bloqueo. Además, mantenga Unity ejecutándose en segundo plano habilitando la opción adecuada en la configuración del reproductor.
La estrategia más conocida es utilizar ENet en un subproceso de E/S independiente y utilizar técnicas de mensajería entre subprocesos para transferir datos entre subprocesos/tareas sin ningún bloqueo/mutex. Las colas sin bloqueo como Ring Buffer se diseñaron para tales fines. Las abstracciones y la lógica de alto nivel se pueden paralelizar utilizando trabajadores, luego comunicarse con subprocesos de E/S y poner en cola/quitar mensajes para enviar/recibir datos a través de la red.
En general, ENet no es seguro para subprocesos, pero algunas de sus funciones se pueden utilizar de forma segura si el usuario es lo suficientemente cuidadoso:
La estructura Packet
y sus funciones son seguras hasta que un paquete solo se mueve a través de subprocesos por valor y no se utiliza un asignador de memoria personalizado.
Peer.ID
tan pronto como se obtenga un puntero a un par desde el lado nativo, el ID se almacenará en caché en la estructura Peer
para acciones adicionales con objetos asignados a ese ID. La estructura Peer
se puede mover a través de subprocesos por valor, pero sus funciones no son seguras para subprocesos porque el servicio en otro subproceso puede cambiar los datos en la memoria.
Library.Time
utiliza primitivas atómicas internamente para gestionar el tiempo monótono local.
Definiciones de indicadores para la función Peer.Send()
:
PacketFlags.None
secuenciado no confiable, la entrega del paquete no está garantizada.
PacketFlags.Reliable
Secuenciado confiable y confiable, el par de destino debe recibir un paquete y se deben realizar intentos de reenvío hasta que se entregue el paquete.
PacketFlags.Unsequenced
Un paquete no secuenciado no se secuenciará con otros paquetes y puede entregarse desordenado. Esta bandera hace que la entrega no sea confiable.
PacketFlags.NoAllocate
un paquete no asignará datos y el usuario debe proporcionarlos en su lugar. Se debe realizar un seguimiento de la vida útil del paquete mediante la devolución de llamada PacketFreeCallback
.
PacketFlags.UnreliableFragmented
un paquete se fragmentará de manera no confiable si excede la MTU. De forma predeterminada, los paquetes no confiables que exceden la MTU se fragmentan y se transmiten de manera confiable. Este indicador debe usarse para indicar explícitamente paquetes que no deben seguir siendo confiables.
PacketFlags.Instant
un paquete no se agrupará con otros paquetes en la siguiente iteración del servicio y, en su lugar, se enviará instantáneamente. Este tipo de entrega cambia la eficiencia de multiplexación a favor de la latencia. El mismo paquete no se puede utilizar para múltiples llamadas de Peer.Send()
.
PacketFlags.Unthrottled
un paquete que estaba en cola para envío de manera no confiable no debe descartarse debido a la limitación y enviarse si es posible.
PacketFlags.Sent
Se envió un paquete desde todas las colas en las que ingresó.
Definiciones de tipos de eventos para la propiedad Event.Type
:
EventType.None
no se produjo ningún evento dentro del límite de tiempo especificado.
EventType.Connect
se ha completado una solicitud de conexión iniciada por la función Peer.Connect()
. Event.Peer
devuelve un par que se conectó exitosamente. Event.Data
devuelve los datos proporcionados por el usuario que describen la conexión o 0 si no hay ninguno disponible.
EventType.Disconnect
un par se ha desconectado. Este evento se genera al completar exitosamente una desconexión iniciada por la función Peer.Disconnect()
. Event.Peer
devuelve un par que se desconectó. Event.Data
devuelve los datos proporcionados por el usuario que describen la desconexión o 0 si no hay ninguno disponible.
EventType.Receive
Se ha recibido un paquete de un par. Event.Peer
devuelve un par que envió el paquete. Event.ChannelID
especifica el número de canal en el que se recibió el paquete. Event.Packet
devuelve un paquete que se recibió y este paquete debe destruirse usando la función Event.Packet.Dispose()
después de su uso.
EventType.Timeout
se agotó el tiempo de espera de un par. Este evento ocurre si se agotó el tiempo de espera de un par o si se agotó el tiempo de espera de una solicitud de conexión inicializada por Peer.Connect()
. Event.Peer
devuelve un par cuyo tiempo de espera se agotó.
Definiciones de estados pares para la propiedad Peer.State
:
PeerState.Uninitialized
un par no inicializado.
PeerState.Disconnected
un par desconectado o agotado el tiempo de espera.
PeerState.Connecting
una conexión de igual en curso.
PeerState.Connected
un par conectado exitosamente.
PeerState.Disconnecting
una desconexión de pares en curso.
PeerState.Zombie
un par no desconectado correctamente.
Proporciona eventos por aplicación.
AllocCallback(IntPtr size)
notifica cuando se solicita una memoria para su asignación. Espera un puntero a la memoria recién asignada. Se debe evitar que una referencia al delegado sea recolectada como basura.
FreeCallback(IntPtr memory)
notifica cuándo se puede liberar la memoria. Se debe evitar que una referencia al delegado sea recolectada como basura.
NoMemoryCallback()
notifica cuando la memoria no es suficiente. Se debe evitar que una referencia al delegado sea recolectada como basura.
Proporciona eventos por paquete.
PacketFreeCallback(Packet packet)
notifica cuando se está destruyendo un paquete. Indica si se reconoció un paquete confiable. Se debe evitar que una referencia al delegado sea recolectada como basura.
Proporciona eventos por anfitrión.
InterceptCallback(ref Event @event, ref Address address, IntPtr receivedData, int receivedDataLength)
notifica cuando se intercepta un paquete UDP sin formato. El código de estado devuelto por esta devolución de llamada indica a ENet cómo se debe manejar el evento establecido. Devolver 1 indica el envío del evento establecido por parte del servicio. Devolver 0 indica que los subsistemas ENet deben manejar los datos recibidos. Devolver -1 indica un error. Se debe evitar que una referencia al delegado sea recolectada como basura.
ChecksumCallback(IntPtr buffers, int bufferCount)
notifica cuándo se debe calcular una suma de verificación para los buffers en el envío y la recepción. Un valor devuelto por esta devolución de llamada es una suma de comprobación de 64 bits. ENet maneja automáticamente la verificación de la integridad de los paquetes si se habilita un mecanismo de suma de verificación en ambos extremos. Se puede utilizar con la función ENet.Library.CRC64()
. Se debe evitar que una referencia al delegado sea recolectada como basura.
Contiene una estructura con datos de host anónimos y número de puerto.
Address.Port
obtiene o establece un número de puerto.
Address.GetIP()
obtiene una dirección IP.
Address.SetIP(string ip)
establece una dirección IP. Para utilizar la transmisión IPv4 en la red local, la dirección se puede configurar en 255.255.255.255 para un cliente. ENet responderá automáticamente a la transmisión y actualizará la dirección a la IP real de un servidor.
Address.GetHost()
intenta realizar una búsqueda inversa desde la dirección. Devuelve una cadena con un nombre resuelto o una dirección IP.
Address.SetHost(string hostName)
establece el nombre del host o una dirección IP. Debe usarse para vincularse a una interfaz de red o para conectarse a un host externo. Devuelve verdadero en caso de éxito o falso en caso de error.
Contiene una estructura con el tipo de evento, el puntero administrado al par, el ID del canal, los datos proporcionados por el usuario y el puntero administrado al paquete.
Event.Type
devuelve un tipo de evento.
Event.Peer
devuelve un par que generó un evento de conexión, desconexión, recepción o tiempo de espera.
Event.ChannelID
devuelve un ID de canal en el par que generó el evento, si corresponde.
Event.Data
devuelve los datos proporcionados por el usuario, si corresponde.
Event.Packet
devuelve un paquete asociado con el evento, si corresponde.
Contiene un puntero administrado al paquete.
Packet.Dispose()
destruye el paquete. Se debe llamar solo cuando el paquete se obtuvo del evento EventType.Receive
.
Packet.IsSet
devuelve un estado del puntero administrado.
Packet.Data
devuelve un puntero administrado al paquete de datos.
Packet.UserData
obtiene o establece los datos proporcionados por el usuario.
Packet.Length
devuelve la longitud de la carga útil del paquete.
Packet.HasReferences
comprueba las referencias al paquete.
Packet.SetFreeCallback(PacketFreeCallback callback)
establece la devolución de llamada para notificar cuando se está destruyendo un paquete apropiado. Se puede utilizar un puntero IntPtr
a una devolución de llamada en lugar de una referencia a un delegado.
Packet.Create(byte[] data, int offset, int length, PacketFlags flags)
crea un paquete que puede enviarse a un par. El parámetro de desplazamiento indica el punto inicial de los datos en una matriz, la longitud es el punto final de los datos en una matriz. Todos los parámetros son opcionales. Se pueden especificar varios indicadores de paquetes a la vez. Se puede utilizar un puntero IntPtr
a un búfer nativo en lugar de una referencia a una matriz de bytes.
Packet.CopyTo(byte[] destination)
copia la carga útil del paquete a la matriz de destino.
Contiene un puntero administrado al igual y un ID almacenado en caché.
Peer.IsSet
devuelve un estado del puntero administrado.
Peer.ID
devuelve un ID de igual. Siempre es cero en el lado del cliente.
Peer.IP
devuelve una dirección IP en un formato imprimible.
Peer.Port
devuelve un número de puerto.
Peer.MTU
devuelve una MTU.
Peer.State
devuelve un estado de igual descrito en la enumeración PeerState
.
Peer.RoundTripTime
devuelve un tiempo de ida y vuelta en milisegundos.
Peer.LastRoundTripTime
devuelve un tiempo de ida y vuelta desde la última confirmación en milisegundos.
Peer.LastSendTime
devuelve la hora de envío del último paquete en milisegundos.
Peer.LastReceiveTime
devuelve la hora de recepción del último paquete en milisegundos.
Peer.PacketsSent
devuelve un número total de paquetes enviados durante la conexión.
Peer.PacketsLost
devuelve una cantidad total de paquetes que se consideraron perdidos durante la conexión según la lógica de retransmisión.
Peer.PacketsThrottle
devuelve una proporción de aceleración de paquetes según las condiciones de la conexión con el par.
Peer.BytesSent
devuelve un número total de bytes enviados durante la conexión.
Peer.BytesReceived
devuelve un número total de bytes recibidos durante la conexión.
Peer.Data
obtiene o establece los datos proporcionados por el usuario. Debe usarse con una conversión explícita al tipo de datos apropiado.
Peer.ConfigureThrottle(uint interval, uint acceleration, uint deceleration, uint threshold)
configura el parámetro del acelerador para un par. ENet descarta los paquetes no confiables en respuesta a las condiciones variables de la conexión con el par. El acelerador representa una probabilidad de que ENet no deba descartar un paquete no confiable y, por lo tanto, ENet lo envíe al igual. El tiempo medio de ida y vuelta más bajo desde el envío de un paquete confiable hasta la recepción de su acuse de recibo se mide durante un período de tiempo especificado por el parámetro de intervalo en milisegundos. Si el tiempo de ida y vuelta medido resulta ser significativamente menor que el tiempo medio de ida y vuelta medido durante el intervalo, entonces la probabilidad de aceleración se incrementa para permitir más tráfico en una cantidad especificada en el parámetro de aceleración, que es una relación con la Library.throttleScale
constante. Si el tiempo de ida y vuelta medido resulta ser significativamente mayor que el tiempo medio de ida y vuelta medido durante el intervalo, entonces la probabilidad de aceleración se reduce para limitar el tráfico en una cantidad especificada en el parámetro de desaceleración, que es una relación con la Library.throttleScale
constante Library.throttleScale
. Cuando el acelerador tiene un valor de Library.throttleScale
, ENet no descarta ningún paquete no confiable, por lo que se enviará el 100% de todos los paquetes no confiables. Cuando el acelerador tiene un valor de 0, ENet descarta todos los paquetes no confiables y, por lo tanto, se enviará el 0% de todos los paquetes no confiables. Los valores intermedios para el acelerador representan probabilidades intermedias entre 0% y 100% de que se envíen paquetes no confiables. Los límites de ancho de banda de los hosts locales y extranjeros se tienen en cuenta para determinar un límite sensible para la probabilidad de aceleración por encima del cual no debería aumentar ni siquiera en las mejores condiciones. Para desactivar la aceleración, el parámetro de desaceleración debe establecerse en cero. El parámetro de umbral se puede utilizar para reducir la limitación de paquetes en relación con el tiempo de ida y vuelta medido en entornos de red inestables con alta fluctuación y baja latencia promedio, que es una condición común para las redes Wi-Fi en lugares concurridos. De forma predeterminada, el parámetro de umbral está establecido en Library.throttleThreshold
en milisegundos.
Peer.Send(byte channelID, ref Packet packet)
pone en cola un paquete para enviarse. Devuelve verdadero en caso de éxito o falso en caso de error.
Peer.Receive(out byte channelID, out Packet packet)
intenta sacar de la cola cualquier paquete entrante en cola. Devuelve verdadero si un paquete fue retirado de la cola o falso si no hay paquetes disponibles.
Peer.Ping()
envía una solicitud de ping a un par. ENet hace ping automáticamente a todos los pares conectados a intervalos regulares; sin embargo, se puede llamar a esta función para garantizar solicitudes de ping más frecuentes.
Peer.PingInterval(uint interval)
establece un intervalo en el que se enviarán pings a un par. Los pings se utilizan para monitorear la vida de la conexión y también para ajustar dinámicamente el acelerador durante períodos de poco tráfico para que el acelerador tenga una capacidad de respuesta razonable durante los picos de tráfico.
Peer.Timeout(uint timeoutLimit, uint timeoutMinimum, uint timeoutMaximum)
establece parámetros de tiempo de espera para un par. Los parámetros de tiempo de espera controlan cómo y cuándo un interlocutor expirará debido a una falla al reconocer el tráfico confiable. Valores de tiempo de espera utilizados en el mecanismo semilineal, donde si un paquete confiable no se reconoce dentro de un tiempo promedio de ida y vuelta más una tolerancia de variación hasta que el tiempo de espera alcance un límite establecido. Si el tiempo de espera está en este límite y se han enviado paquetes confiables pero no se han reconocido dentro de un período de tiempo mínimo determinado, el interlocutor se desconectará. Alternativamente, si se enviaron paquetes confiables pero no se confirmaron durante un período de tiempo máximo determinado, el interlocutor se desconectará independientemente del valor límite de tiempo de espera actual.
Peer.Disconnect(uint data)
solicita una desconexión de un par.
Peer.DisconnectNow(uint data)
fuerza una desconexión inmediata de un par.
Peer.DisconnectLater(uint data)
solicita una desconexión de un par, pero solo después de que se hayan enviado todos los paquetes salientes en cola.
Peer.Reset()
desconecta por la fuerza a un par. El host extranjero representado por el par no recibe notificación de la desconexión y su conexión con el host local expirará.
Contiene un puntero administrado al host.
Host.Dispose()
destruye el host.
Host.IsSet
devuelve un estado del puntero administrado.
Host.PeersCount
devuelve una cantidad de pares conectados.
Host.PacketsSent
devuelve una cantidad total de paquetes enviados durante la sesión.
Host.PacketsReceived
devuelve un número total de paquetes recibidos durante la sesión.
Host.BytesSent
devuelve un número total de bytes enviados durante la sesión.
Host.BytesReceived
devuelve un número total de bytes recibidos durante la sesión.
Host.Create(Address? address, int peerLimit, int channelLimit, uint incomingBandwidth, uint outgoingBandwidth, int bufferSize)
crea un host para comunicarse con pares. Los parámetros de ancho de banda determinan el tamaño de la ventana de una conexión, lo que limita la cantidad de paquetes confiables que pueden estar en tránsito en un momento dado. ENet colocará paquetes estratégicamente en lados específicos de una conexión entre hosts para garantizar que el ancho de banda del host no se vea abrumado. El parámetro de tamaño de búfer se utiliza para establecer el tamaño del búfer del socket para enviar y recibir datagramas. Todos los parámetros son opcionales excepto la dirección y el límite de pares en los casos en que la función se utiliza para crear un host que escuchará las conexiones entrantes.
Host.PreventConnections(bool state)
impide el acceso al host para nuevas conexiones entrantes. Esta función hace que el host sea completamente invisible en la red; cualquier interlocutor que intente conectarse a él expirará.
Host.Broadcast(byte channelID, ref Packet packet, Peer[] peers)
pone en cola un paquete para enviarlo a un rango de pares o a todos los pares asociados con el host si no se utiliza el parámetro de pares opcional. Cualquier estructura Peer
puesta a cero en una matriz se excluirá de la transmisión. En lugar de una matriz, se puede pasar un único Peer
a la función que será excluida de la transmisión.
Host.CheckEvents(out Event @event)
busca eventos en cola en el host y envía uno si está disponible. Devuelve > 0 si se envió un evento, 0 si no hay eventos disponibles, < 0 en caso de error.
Host.Connect(Address address, int channelLimit, uint data)
inicia una conexión a un host externo. Devuelve un par que representa el host externo en caso de éxito o genera una excepción en caso de error. El par devuelto no habrá completado la conexión hasta que Host.Service()
notifique un evento EventType.Connect
. El límite de canales y los parámetros de datos proporcionados por el usuario son opcionales.
Host.Service(int timeout, out Event @event)
espera eventos en el host especificado y transfiere paquetes entre el host y sus pares. ENet utiliza un modelo de eventos encuestados para notificar al usuario sobre eventos importantes. Los hosts de ENet son sondeados en busca de eventos con esta función, donde se puede especificar un valor de tiempo de espera opcional en milisegundos para controlar cuánto tiempo sondeará ENet. Si se especifica un tiempo de espera de 0, esta función regresará inmediatamente si no hay eventos para enviar. De lo contrario, devolverá 1 si se envió un evento dentro del tiempo de espera especificado. Esta función debe llamarse periódicamente para garantizar que los paquetes se envíen y reciban; de lo contrario, se producirán picos de tráfico que provocarán una mayor latencia. El parámetro de tiempo de espera establecido en 0 significa no bloqueo, lo cual es necesario en los casos en que la función se llama en un bucle de juego.
Host.SetBandwidthLimit(uint incomingBandwidth, uint outgoingBandwidth)
ajusta los límites de ancho de banda de un host en bytes por segundo.
Host.SetChannelLimit(int channelLimit)
limita el máximo de canales permitidos para futuras conexiones entrantes.
Host.SetMaxDuplicatePeers(ushort number)
limita el número máximo de pares duplicados permitidos desde el mismo host e impide la conexión si se excede. De forma predeterminada, está configurado en Library.maxPeers
, no puede ser menos de uno.
Host.SetInterceptCallback(InterceptCallback callback)
establece la devolución de llamada para notificar cuando se intercepta un paquete UDP sin formato. Se puede utilizar un puntero IntPtr
a una devolución de llamada en lugar de una referencia a un delegado.
Host.SetChecksumCallback(ChecksumCallback callback)
establece la devolución de llamada para notificar cuándo se debe calcular una suma de verificación. Se puede utilizar un puntero IntPtr
a una devolución de llamada en lugar de una referencia a un delegado.
Host.Flush()
envía cualquier paquete en cola en el host especificado a sus pares designados.
Contiene campos constantes.
Library.maxChannelCount
el número máximo posible de canales.
Library.maxPeers
el número máximo posible de pares.
Library.maxPacketSize
el tamaño máximo de un paquete.
Library.version
la versión de compatibilidad actual relativa a la biblioteca nativa.
Library.Time
devuelve una hora monótona local actual en milisegundos. Nunca se reinicia mientras la aplicación permanece activa.
Library.Initialize(Callbacks callbacks)
inicializa la biblioteca nativa. El parámetro de devolución de llamadas es opcional y debe usarse solo con un asignador de memoria personalizado. Se debe llamar antes de iniciar el trabajo. Devuelve verdadero en caso de éxito o falso en caso de error.
Library.Deinitialize()
desinicializa la biblioteca nativa. Se debe llamar una vez finalizado el trabajo.
Library.CRC64(IntPtr buffers, int bufferCount)
calcula una suma de comprobación para los buffers no administrados.
Este proyecto está patrocinado por:
Entretenimiento de ardilla voladora
Estudios de raíz cuadrada
Juegos de bucles extraños