リンク中...
ライブラリ .\Release/Test.lib とオブジェクト .\Release/Test.exp を作成中
Test.exp : error LNK2001: 外部シンボル "_TestFunction@16" は未解決です
Test.exp : error LNK2001: 外部シンボル "_TestFunction@16" は未解決です
.\Release\Test.dll : fatal error LNK1120: 外部参照 1 が未解決です。
link.exe の実行エラー
Test.dll - エラー 3、警告 0
と、結構ありがちなエラー。外部シンボルが未解決というと、.defファイルに書いてる関数名が間違っているというのがパターンなんですが、何度見直しても合ってるし……。.defファイルはこんな感じ。
EXPORTS
TestFunction = _TestFunction@16 ;VB用の export
_TestFunction@16 ;VC用の export
関数名は合ってると。では怪しいのは @16 なんだけどこれって何?
.defファイルの書式やらをググると、@の後の数字は序数で……とか書いてあったりするのですが、この場合は違いました。さらにキーワードを変えつつググっていたら、やっとそれらしい情報に到達。
C の装飾名の形式
関数宣言時の呼び出し規約が __stdcall の場合、.defファイルで記述するCの装飾名の形式は、
先頭にアンダースコア (_) が付き、末尾にアット マーク (@) が付き、その後ろにパラメータ リストのバイト数が続きます。
ということでした。つまり @16 というのは関数の引数リストのバイト数合計が16バイトということだったのですね。
今回は引数を追加したわけなので、そのバイト数分増やさないといけなかったのです。
4バイトの引数を1個追加したので、@16 → @20 に修正してリビルドしたら……リンク通りました。
なんかこれだけ調べるのに丸1日以上かかってしまったよ。とほほ。最初はVC6の環境がなくてVC2005で開いてやってたから、そのせいかもと思って古い環境でやり直したりとか……。
DLLの作成方法にはいろいろあって、.defを使用しない方法もあるんですけど、今回は修正元が使ってたのをそのまま使ったので。
0 件のコメント:
コメントを投稿