1

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

これをビルドしようとすると、次のリンカーエラーが発生します。

ErlDriver.obj:エラーLNK2019:関数__driver_outputで参照されている未解決の外部シンボル_WinDynDriverCallbacks

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

したがって、ご覧のとおり、WinDynDriverCallbacksは宣言されて定義されています。

では、何がリンカーエラーを引き起こしているのでしょうか?

4

4 に答える 4

2

いいえ、定義されていません(少なくともあなたが引用したものでは)。宣言されています。「extern」キーワードは、「このシンボルの定義が別のコンパイル単位(ソースファイル)に表示される」ことを意味します。そのシンボルを定義するソースファイルをコンパイルして作成されたオブジェクトファイル(またはライブラリ)とリンクする必要があります。

于 2009-08-27T21:21:55.377 に答える
1

WindowsでNIFを構築する際に非常によく似た問題が発生しました。未解決の外部シンボル _WinDynNifCallbacks。これは ERL_NIF_INIT マクロによって定義されていることがわかりました。私の場合、マクロ全体を extern C ブロックで囲む必要がありました。

つまり、これは失敗しました

extern "C" ERL_NIF_INIT(...)

これが成功している間

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

この問題は同じ問題によるものと強く思われますが、erlang ポート ドライバーの DRIVER_INIT マクロが原因です。

于 2011-12-22T11:51:59.727 に答える
1

何かを「宣言」することと、C または C++ でそれを「定義」することには微妙な違いがあります。宣言すると、特定のシンボルが別の場所で定義されることがコンパイラに通知されます。これにより、コードは実際の定義を確認する必要なく、そのシンボルを使用できます。リンクされているコードのどこかにシンボルを定義する必要があります。そうしないと、表示されているエラー メッセージが表示されます。

たとえば、これはシンボルの宣言ですWinDynDriverCallbacks:

extern TWinDynDriverCallbacks WinDynDriverCallbacks;

コードにはこの宣言があります。これにより、シンボルを使用するコードを正常にコンパイルできます (ただし、リンクはできません)。

どこかに定義を追加する必要があります。

TWinDynDriverCallbacks WinDynDriverCallbacks;

定義は、ソース コード ファイルのどこかに入れる必要があります (通常はヘッダー ファイルではありません)。これにより、そのオブジェクトのオブジェクト コードに領域を割り当てるようにコンパイラに指示し、プログラムが正常にリンクできるようにします。

于 2009-08-27T21:38:07.713 に答える
0

Driver_Init は、「TWinDynDriverCallbacks WinDynDriverCallbacks;」を宣言するメイン ループです。しかし、driver_init の複数行の定義で適切に宣言されています。extern "c" でラップする必要はありません。

このスレッドは、ベアボーンの erlang ポート ドライバーをセットアップしようとしているときに約 100 万回発生したため、ここで述べます。私は Joe Armstrong のプログラミング erlang の本、第 12 章のインターフェイス手法に取り組んでいます。erl5.9 と vs2010 を使用。

本のコードはexample1_lib.cに抜けと誤りがありました。エラーの原因としては、書籍の古さと erlang のバージョンの変更が原因である可能性が最も高いです。

example1_lib.c の一番上に(#define WIN32 ) を設定する必要がありました。そうしないと、erlang はすべての Linux オプションにデフォルト設定されました。

次に、example_drv_output で (int bufflen) を (ErlDrvSizeT bufflen) に変更する必要がありました。

その後、きれいにビルドされました。

于 2013-02-14T19:44:29.663 に答える