Question

Je suis en train de construire une bibliothèque wrapper avec le compilateur de VC ++.

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

Lorsque je tente de construire cela, j'obtiens l'erreur d'éditeur de liens suivant:

  

ErlDriver.obj: erreur LNK2019: _WinDynDriverCallbacks symbole externe non résolu référencé dans la fonction __driver_output

erl_win_dyn_driver.h (inclus dans 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)

Donc, comme vous pouvez le voir, WinDynDriverCallbacks est définie déclarée.

Ce qui pourrait être à l'origine de l'erreur de liaison, alors?

Était-ce utile?

La solution

Il y a une différence subtile entre « déclarant » quelque chose et « définir » en C ou C ++. Lorsque vous déclarez, il indique au compilateur qu'un certain symbole sera défini quelque part ailleurs - cela peut permettre le code à utiliser ce symbole sans avoir besoin de voir la définition réelle. Il vous reste à définir le symbole quelque part dans le code qui est lié à, ou bien vous obtiendrez le message d'erreur que vous voyez.

Par exemple, ceci est une déclaration du symbole WinDynDriverCallbacks:

extern TWinDynDriverCallbacks WinDynDriverCallbacks;

Votre code a cette déclaration - il permet le code qui utilise le symbole pour compiler avec succès (mais pas le lien)

.

Vous devez ajouter une définition quelque part:

TWinDynDriverCallbacks WinDynDriverCallbacks;

La définition doit aller dans un fichier de code source quelque part (généralement pas dans un fichier d'en-tête). Cela indique au compilateur d'allouer l'espace dans le code d'objet pour cet objet et permet au programme de lien avec succès.

Autres conseils

Non, ce n'est pas défini (au moins dans ce que vous avez cité). Il est déclaré. Les moyens de mot-clé « extern » « la définition de ce symbole apparaît dans une autre unité de compilation (fichier source). » Vous devez être lier avec le fichier objet (ou bibliothèque) produit à partir de la compilation du fichier source qui définit ce symbole.

Je suis un problème très similaire la construction d'un NIF sous Windows. _WinDynNifCallbacks de symboles externes non résolues. Transforme c'est défini par la macro ERL_NIF_INIT et dans mon cas l'ensemble macro devait être enfermé dans un bloc extern C.

-à-dire cela a échoué

extern "C" ERL_NIF_INIT(...)

alors que cette réussi

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

Je soupçonne fortement ce problème est dû à la même question, mais avec la macro DRIVER_INIT pour un pilote de port Erlang.

Driver_Init est la boucle principale qui déclare "TWinDynDriverCallbacks WinDynDriverCallbacks;" mais il est bien déclaré dans la ligne multiple pour définir driver_init. Vous ne devriez pas avoir besoin de l'envelopper dans extern « c ».

car ce fil est venu d'un million de fois sur tout en essayant d'installer mon barebone pilote de port Erlang je vais dire ici. Je travaille sur la programmation du livre de Erlang Joe Armstrong, chapitre 12 techniques d'interface. En utilisant erl5.9 et VS2010.

Le code dans le livre avait une omission et une erreur dans example1_lib.c. Bien que l'erreur est très probablement due à l'âge du livre par rapport à des changements de version Erlang.

Nécessaire pour régler (#define WIN32 ) au sommet de example1_lib.c autrement Erlang par défaut à toutes les options Linux.

Deuxième nécessaire pour changer (int bufflen) à (ErlDrvSizeT bufflen) dans example_drv_output.

Après cela, il construit propre.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top