Domanda

Sto cercando di costruire una libreria wrapper con il compilatore 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

Quando si tenta di costruire questo, ottengo il seguente errore di linker:

  

ErlDriver.obj: LNK2019 di errore: non risolti _WinDynDriverCallbacks simbolo esterno a cui fa riferimento la funzione __driver_output

erl_win_dyn_driver.h (incluso nel 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)

Quindi, come potete vedere, è WinDynDriverCallbacks definito dichiarato.

Quale potrebbe essere la causa del errore di linker, allora?

È stato utile?

Soluzione

C'è una sottile differenza tra "dichiarando" qualcosa e "definire" in C o C ++. Quando si dichiara, esso dice al compilatore che un certo simbolo sarà definito da qualche altra parte - questo può consentire il codice per utilizzare quel simbolo senza bisogno di vedere la definizione stessa. Hai ancora a definire il simbolo da qualche parte nel codice che è collegato in, altrimenti si otterrà il messaggio di errore che state vedendo.

Ad esempio, questo è un dichiarazione del WinDynDriverCallbacks simbolo:

extern TWinDynDriverCallbacks WinDynDriverCallbacks;

Il tuo codice ha questa dichiarazione - consente il codice che utilizza il simbolo per compilare correttamente (ma non link)

.

È necessario aggiungere una definizione da qualche parte:

TWinDynDriverCallbacks WinDynDriverCallbacks;

La definizione deve andare in un file di codice sorgente da qualche parte (in genere non in un file di intestazione). Questo dice al compilatore di allocare lo spazio nel codice oggetto per l'oggetto e permette al programma di collegare con successo.

Altri suggerimenti

No, non è definito (almeno in quello che lei ha citato). E 'dichiarato. La parola chiave "extern" significa "la definizione di questo simbolo appare in un'altra unità di compilazione (file di origine)." Hai bisogno di essere il collegamento con il file oggetto (o libreria) prodotto dalla compilazione del file sorgente che definisce quel simbolo.

Ho un problema molto simile costruzione di un NIF su Windows. Non risolte _WinDynNifCallbacks simbolo esterno. Si scopre che questo è definito dalla macro ERL_NIF_INIT e nel mio caso l'intera macro doveva essere racchiusa in un blocco C extern.

vale a dire questo non è riuscito

extern "C" ERL_NIF_INIT(...)

Anche se questo è riuscito

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

Ho il forte sospetto questo problema è dovuto alla stessa questione, ma con la macro DRIVER_INIT per un driver di porta Erlang.

Driver_Init è il ciclo principale che dichiara "TWinDynDriverCallbacks WinDynDriverCallbacks;" ma è correttamente dichiarato nella linea multipla definire per driver_init. Non dovrebbe essere necessario per avvolgerla in extern "C".

dal momento che questa discussione è venuto circa un milione di volte durante il tentativo di installare il mio driver della porta Erlang barebone Dirò questo qui. Sto lavorando fuori programmazione Erlang libro di Joe Armstrong, il capitolo 12 interfacciamento tecniche. Utilizzando erl5.9 e VS2010.

Il codice nel libro aveva un'omissione e un errore di example1_lib.c. Anche se l'errore è più probabile a causa dell'età del libro contro Erlang versione modifiche.

Necessario per impostare (#define WIN32 ) al vertice della example1_lib.c altrimenti Erlang in default a tutte le opzioni di Linux.

In secondo luogo necessario per cambiare (int bufflen) a (ErlDrvSizeT bufflen) in example_drv_output.

Dopo di che ha costruito pulita.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top