Pregunta

Estoy tratando de construir una biblioteca envoltorio con el compilador VC ++ 's.

ErlDriver.c

#define __WIN32__
#define DLL_EXPORT __declspec(dllexport)

#include "erl_driver.h"

DLL_EXPORT int _driver_output(ErlDrvPort port, char *buf, int len) {
    return driver_output(port, buf, len);
}

build.bat

cl /I%ERL_DRIVER_H% /LD /MD ErlDriver.c

Cuando se intenta generar esto, me sale el siguiente error de vinculador:

  

ErlDriver.obj: LNK2019 error: no resueltos _WinDynDriverCallbacks símbolo externos referenciados en función __driver_output

erl_win_dyn_driver.h (incluido en erl_driver.h )

typedef struct {
    WDD_FTYPE(driver_output) *driver_output;
    // a ton more of those
} TWinDynDriverCallbacks;

extern TWinDynDriverCallbacks WinDynDriverCallbacks;

#define driver_output (WinDynDriverCallbacks.driver_output)

Por lo tanto, como se puede ver, es WinDynDriverCallbacks definido declarado.

¿Cuál podría ser la causa del error de vinculador, entonces?

¿Fue útil?

Solución

Hay una sutil diferencia entre "declarar" algo y "definir" en C o C ++. Cuando se declara que, le dice al compilador que un cierto símbolo se define en otro lugar - esto puede permitir que el código para usar ese símbolo sin necesidad de ver la definición real. Usted todavía tiene que definir el símbolo en alguna parte del código que está en el mismo, o de lo contrario obtendrá el mensaje de error que está viendo.

Por ejemplo, esta es una declaración del símbolo WinDynDriverCallbacks:

extern TWinDynDriverCallbacks WinDynDriverCallbacks;

Su código tiene esta declaración - que permite que el código que utiliza el símbolo para compilar correctamente (pero no enlace)

.

Es necesario añadir una definición alguna parte:

TWinDynDriverCallbacks WinDynDriverCallbacks;

La definición debe ir en un archivo de código fuente en alguna parte (no generalmente en un fichero de cabecera). Esto le dice al compilador para asignar espacio en el código objeto para ese objeto y permite que el programa para vincular con éxito.

Otros consejos

No, no está definido (al menos en lo que usted ha citado). Se declaró. La palabra clave "externo" significa "la definición de este símbolo aparece en otra unidad de compilación (archivo de origen)." Es necesario que se une con el archivo de objeto (o biblioteca) producido a partir de la elaboración del expediente de origen que define ese símbolo.

Tengo un problema muy similar construcción de un NIF en Windows. Sin resolver _WinDynNifCallbacks símbolos externos. Resulta que este es definido por la macro ERL_NIF_INIT y en mi caso toda la macro necesaria para ser encerrado en un bloque C externo.

es decir, este no

extern "C" ERL_NIF_INIT(...)

Mientras que esto sucedió

extern "C"
{
   ERL_NIF_INIT(...)
}

Tengo la firme sospecha este problema se debe a la misma cuestión, pero con la macro DRIVER_INIT para un controlador de puerto de Erlang.

Driver_Init es el bucle principal que declara "TWinDynDriverCallbacks WinDynDriverCallbacks;" pero ha declarado correctamente en el registro de varias líneas para definir driver_init. No debería ser necesario para envolverlo en extern "C".

ya que este hilo se acercó un millón de veces al tratar de configurar mi controlador de puerto Erlang barebones que voy a decir esto aquí. Estoy trabajando fuera del libro de programación Erlang Joe Armstrong, capítulo 12 técnicas de interconexión. Usando erl5.9 y VS2010.

El código en el libro tenía una omisión y un error en example1_lib.c. Aunque es muy probable que el error debido a la antigüedad del libro frente a los cambios de versión de Erlang.

Se necesita establecer (#define WIN32 ) en la parte superior de otra manera example1_lib.c Erlang por defecto en todas las opciones de Linux.

En segundo lugar es necesario cambiar (int bufflen) a (ErlDrvSizeT bufflen) en example_drv_output.

Después de que se construyó limpio.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top