「 error LNK2019: 未解決の外部シンボル」について

解決


コウ  2009-02-21 14:17:22  No: 69716  IP: 192.*.*.*

VC++6.0で作成されたDLL内のメソッドをVC++2008で利用しようとすると
コンパイルは通るのですが最後のリンク付けでエラーになってしまいます。

--- エラー内容 ---
1>TestCtrl.obj : error LNK2001: 外部シンボル ""__declspec(dllimport) int __stdcall Test01(wchar_t *)" (__imp_?Test01@@YGHPA_W@Z)" は未解決です。
1>C:\work\ソース\Test01\Debug\Test01.ocx : fatal error LNK1120: 外部参照 1 が未解決です。
-------------------

手元には使用したいDLLのライブラリファイル(*.lib)と
ヘッダファイル(*.h)がありプロパティの設定でビルド時に
読み込むようにはなっています。
# *.libファイルの中身をみたところ使用したいメソッドは存在している
# ようにみえます。


プロジェクト自体はMFCで作成しています。

以上、よろしくお願いします。

編集 削除
wclrp ( 'o')  2009-02-21 15:25:22  No: 69717  IP: 192.*.*.*

でもやっぱり何らかの理由でリンクされていないんだよ。

例えばの話ですけど
使用したいDLLがC言語用に作られていたりすると
VC++はTest01@@YGHPA_W@Zとリンクしようとするから失敗するけど。

編集 削除
コウ  2009-02-21 17:21:48  No: 69718  IP: 192.*.*.*

早速の回答ありがとうございます。

>使用したいDLLがC言語用に作られていたりすると
>VC++はTest01@@YGHPA_W@Zとリンクしようとするから失敗するけど。
DLL自体はVC5.0、6.0++言語用に作られています。
VC++2008ではリンクの仕方が変更になったのですか?

関係ないかもしれませんが、対象のDLLは下記にような感じで定義を
書くとVB2008では読み込めております。
例)
Public Declare Auto Function Test01 Lib "TEST.dll" _

編集 削除
Ban  2009-02-22 23:04:44  No: 69719  IP: 192.*.*.*

もしかして、ですがwchar_tの問題だったりしませんか。
「VC6の頃はデフォルトで(実は)wchar_tではなくunsigned shortでした」のせいか、
もしくは「VC2008はデフォルトがUNICODEです」のいずれかのせいで、
DLL提供関数と、呼び出し側が同じ方と認識されてないとかでは?

# 上記をあわせてだめあなら、インポートライブラリだけ作り直してみるとか。

編集 削除
.....  2009-02-22 23:13:52  No: 69720  IP: 192.*.*.*

> 手元には使用したいDLLのライブラリファイル(*.lib)と
> ヘッダファイル(*.h)があり…

素朴な疑問なんですが
、DLLとLibとをごっちゃにしてません?

編集 削除
コウ  2009-02-22 23:24:15  No: 69721  IP: 192.*.*.*

>もしかして、ですがwchar_tの問題だったりしませんか。
>「VC6の頃はデフォルトで(実は)wchar_tではなくunsigned shortでした」のせいか、
>もしくは「VC2008はデフォルトがUNICODEです」のいずれかのせいで、
>DLL提供関数と、呼び出し側が同じ方と認識されてないとかでは?
Banさん回答ありがとうございます。

わからないなりに休みの間、色々実験していたのですが、全く同じよう
な設定&コードでVC6.0++で作成すると正常にリンクできましたので
Banさんのご指摘通り
文字コードが怪しそうだと結論に達していたところです。

>もしくは「VC2008はデフォルトがUNICODEです」のいずれかのせいで、
>DLL提供関数と、呼び出し側が同じ方と認識されてないとかでは?
ただ原因は何となくわかったのですが、結局どうすれば良いかが
わかりませんでしたorz

Unicodeで作成されたVC2008で読み込む方法はありますでしょうか?

編集 削除
コウ  2009-02-22 23:24:18  No: 69722  IP: 192.*.*.*

>もしかして、ですがwchar_tの問題だったりしませんか。
>「VC6の頃はデフォルトで(実は)wchar_tではなくunsigned shortでした」のせいか、
>もしくは「VC2008はデフォルトがUNICODEです」のいずれかのせいで、
>DLL提供関数と、呼び出し側が同じ方と認識されてないとかでは?
Banさん回答ありがとうございます。

わからないなりに休みの間、色々実験していたのですが、全く同じよう
な設定&コードでVC6.0++で作成すると正常にリンクできましたので
Banさんのご指摘通り
文字コードが怪しそうだと結論に達していたところです。

>もしくは「VC2008はデフォルトがUNICODEです」のいずれかのせいで、
>DLL提供関数と、呼び出し側が同じ方と認識されてないとかでは?
ただ原因は何となくわかったのですが、結局どうすれば良いかが
わかりませんでしたorz

Unicodeで作成されたVC2008で読み込む方法はありますでしょうか?

編集 削除
コウ  2009-02-22 23:39:29  No: 69723  IP: 192.*.*.*

度々の投稿&二重投稿になってしまい申し訳ないです。

補足ですが呼び出したいメソッドは下記にような感じになっています。
__declspec(dllexport) BOOL PASCAL
Test01(
BSTR    bs1,
BSTR    bs2,
BSTR    bs3,
BSTR    bs4,
sint32    bs32,
VARIANT    *v1)
{
            ・
            ・
後、静的呼出はあきらめてAfxLoadLibraryを利用してDLLを動的に
呼び出そうと思ったのですが、メソッドは認識できるようになった
のですが、呼び出すと落っこちてしましましたorz

宣言は以下のような感じでしています。
typedef BOOL (__stdcall  PASCAL *Test01)( BSTR bs1, BSTR bs2, BSTR bs3, BSTR bs4, long bs32, BSTR* v1);

以上、よろしくお願いします。

編集 削除
YuO  2009-02-23 03:10:14  No: 69724  IP: 192.*.*.*

wclrp ( 'o') さんがあたりだと思いますが……。
extern "C"されていないだけではないでしょうか。

編集 削除
tetrapod  2009-02-23 10:25:40  No: 69725  IP: 192.*.*.*

あえてもうちょっと補足などしてみると
C++ ソースファイル中では
extern     __declspec(dllimport) int testfunc(char*); と
extern "C" __declspec(dllimport) int testfunc(char*); とでは
異なる名前修飾が行われ、正しい指定を行っていないと LNK2019

もともとの hoge.lib と hoge.h が C++ ではなく C 用に作られていて
---hoge.h---
extern __declspec(dllimport) int testfunc(char*);
---hoge.h---END
となっている場合、この hoge.h を C++ ソース中で #include "hoge.h"
すると LNK2019 が発生してしまうことになるのだ。
対策:C++ ソース中の当該ファイルを取り込む部分を
extern "C" {
#include "hoge.h"
}
と修正する。

この辺最初に指摘されているのだが、詳細までは書かれていないので
無視したのか、理解できなかったのか・・・

編集 削除
wclrp ( 'o')  2009-02-23 23:00:06  No: 69726  IP: 192.*.*.*

>__declspec(dllexport) BOOL PASCAL
>Test01(
>BSTR bs1,
>BSTR bs2,
>BSTR bs3,
>BSTR bs4,
>sint32 bs32,
>VARIANT *v1)

>宣言は以下のような感じでしています。
>typedef BOOL (__stdcall  PASCAL *Test01)( BSTR bs1, BSTR bs2, BSTR bs3, BSTR bs4, long bs32, BSTR* v1);

一方には__stdcallがあったり、VARIANTだったり違うんですけど。

wchar_t使ってないし。

変じゃね

編集 削除
コウ  2009-02-24 23:51:14  No: 69727  IP: 192.*.*.*

皆様回答ありがとうございました。

YuOさん、tetrapodさん>
extern "C"をする必要はないとの認識です。

wclrpさん>
VC歴5日目の当方の実力では変かどうかはわかりませんorz
只VC6.0++では正常に呼び出せていますので多分問題が
ないのだと思います...

皆様からの指摘&助言を参考にさらに調査したところやなり
文字コードの問題だということがわかり、問題はなんとか
解決することができました。

ありがとうございました。

編集 削除
コウ  2009-02-24 23:51:44  No: 69728  IP: 192.*.*.*

解決選択するのを忘れておりました。

編集 削除