error LNK2028,2019

解決


ds  2010-11-14 19:06:41  No: 72042  IP: 192.*.*.*

このエラーの質問は以前もありませたがよくわかりませんでした。もう一度教えて下さい。CBaseReferenceClockを継承したCClockを作成中ですが、以下ののメッセージで怒られています。(長いので、”2019”は省略)
Player.obj : error LNK2028: 未解決のトークン (0A00019E) "public: __thiscall CBaseReferenceClock::CBaseReferenceClock(wchar_t const *,struct IUnknown *,long *,class CAMSchedule *)" (??0CBaseReferenceClock@@$$FQAE@PB_WPAUIUnknown@@PAJPAVCAMSchedule@@@Z) が関数 "public: __thiscall Player::CClock::CClock(wchar_t const *,struct IUnknown *,long *,class CAMSchedule *)" (??0CClock@Player@@$$FQAE@PB_WPAUIUnknown@@PAJPAVCAMSchedule@@@Z) で参照されました。

定義している(と思っている)はずなのになぜかわかりません。
ビルド設定は/crl、VC++2008Expressです。ソフトの概要は以下です。(長くなるので省略してあります)

やっぱ、コンストラクターがおかしいのでしょうか。
どなたか教えてください。よろしくお願いいたします。


struct CClock : public CBaseReferenceClock
{
  public:
  REFERENCE_TIME now;などの変数宣言

  CClock(LPCTSTR pName, LPUNKNOWN pUnk, HRESULT *phr, CAMSchedule *pSched);// = NULL);コンストラクター
  protected:
  virtual ~CClock();デストラクター

  STDMETHODIMP QueryInterfaceとAddref,Release宣言

  virtual REFERENCE_TIME GetPrivateTime(void);関数宣言

};

STDMETHODIMP CClock::QueryInterface{
        処理;
  }

  CClock::CClock(LPCTSTR pName, LPUNKNOWN pUnk, HRESULT *phr, CAMSchedule *pSched)
: CBaseReferenceClock(NAME("myrefclock"), 0, 0, 0)  コンストラクター
    {rate = 0.5; lastnow = pCB->GetPrivateTime(); initialized = false;}

  CClock::~CClock(){}    デストラクター

  REFERENCE_TIME CClock::GetPrivateTime(void) {
    処理
  }

編集 削除
επιστημη  URL  2010-11-14 22:40:26  No: 72043  IP: 192.*.*.*

ライブラリ:Strmbase.lib(release)/Strmbasd.lib(debug)をリンクし忘れてるんじゃなくて?

編集 削除
ds  2010-11-14 23:01:08  No: 72044  IP: 192.*.*.*

早速のご指摘ありがとうございます。

リンカー入力の設定で取り込んでいます。
また、
#pragma comment(lib,"Strmbasd.lib")
にても試してみましたが、結果は同じでした。

編集 削除
ds  2010-11-14 23:41:40  No: 72045  IP: 192.*.*.*

補足です。

リンカー入力の「親またはプロジェクトの・・・」のチェックも入れてあります。

また、IReferenceClockを継承した場合はこのエラーは発生しません。
どうしてでしょう。もう一か月悩んでいます。

編集 削除
gak  2010-11-15 18:01:49  No: 72046  IP: 192.*.*.*

Strmbasd.lib を作ったときの文字セットは Unicode (利用側プロジェクトと同じ設定)にした?

俺の手元に在る refclock.h は DirectX8 付属のものでかなり古く、最新の .h では変わっているかもしんないが
CBaseReferenceClock のコンストラクタは以下の一つのみ定義されていた。

CBaseReferenceClock(TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr, CAMSchedule * pSched = 0 );

第一引数はTCHAR。つまり作成時の文字セットによって「wchar_t *pName」にも「char *pName」にもなり得る。
例えば Strmbasd.lib がマルチバイト文字セットでビルドされていた場合、CBaseReferenceClock コンストラクタは

CBaseReferenceClock(char *pName, LPUNKNOWN pUnk, HRESULT *phr, CAMSchedule * pSched = 0 );

と定義される。

> public: __thiscall CBaseReferenceClock::CBaseReferenceClock(wchar_t const *, ...
仮にこの通りだった場合、wchar_t* である上記は”未定義”となり LNK2028 辺りが起きる可能性も在りえる。

仮説の域を出ないレスだな…当たってたら儲けモンて事で。

編集 削除
ds  2010-11-15 23:41:20  No: 72047  IP: 192.*.*.*

gakさんありがとうございます。

仮にこの通りだった場合、wchar_t* である上記は”未定義”となり LNK2028 辺りが起きる可能性も在りえる。

のご指摘、実は、この一ヶ月の悩み期間に試しました。
宣言(定義)を、「(wchar_t*)」、「NAME(・・・)」、「etc・・・」
も試してみました。
結果は同じでした。
とほほ・・・・・

編集 削除
gak  2010-11-16 13:00:49  No: 72048  IP: 192.*.*.*

> 宣言(定義)を、「(wchar_t*)」、「NAME(・・・)」、「etc・・・」も試してみました。
ってのは、最初の提示ソースの
> : CBaseReferenceClock(NAME("myrefclock"), 0, 0, 0)  コンストラクター
の部分を色々変えてみたけどダメだったって事を言っている、という認識で合ってる?

> Strmbasd.lib を作ったときの文字セットは Unicode (利用側プロジェクトと同じ設定)にした?
別の聞き方すると、
「今回の場合、MBCS版の Strmbasd.lib では×。ちゃんとUNICODE版の Strmbasd.lib 使ってるか?」
と聞きたかったんだけど、これに対する回答は「大丈夫だ、問題ない」って事で良いのかな?

編集 削除
ds  2010-11-17 21:54:19  No: 72049  IP: 192.*.*.*

gakさん、色々ありがとうございます。
まず、質問の回答ですが、
    > : CBaseReferenceClock(NAME("myrefclock"), 0, 0, 0)  コンストラクター
の部分を色々変えてみたけどダメだったって事を言っている、という認識で合ってる?
ーーー>>>正解です。あっています。
            呼び出し側でも、呼び出され側(COM側)でも考えられるだけの組み合わせはしたつもりです。)


> Strmbasd.lib を作ったときの文字セットは Unicode (利用側プロジェクトと同じ設定)にした?
別の聞き方すると、
「今回の場合、MBCS版の Strmbasd.lib では×。ちゃんとUNICODE版の Strmbasd.lib 使ってるか?」
と聞きたかったんだけど、これに対する回答は「大丈夫だ、問題ない」って事で良いのかな?
ーーーー>>>これは、意味が分りませんでした。詳しく教えてください。
              今の『.Lib』はC++2008Exp.に標準付属のファイルをビルドしたものです。)
もしかして、これですか?

編集 削除
瀬戸っぷ  2010-11-18 00:37:04  No: 72050  IP: 192.*.*.*

C:\Program Files\Microsoft SDKs\Windows\v6.0
って、
Visual C++ 2008 Express Edition
の付属のものでしたかね?
# 自分でDVDイメージをMSのサイトから拾ってきて、SDKをインストールしているので2008EEで入ったモノか判らない。

とりあえず、その下の
Samples\Multimedia\DirectShow\BaseClasses
にあるソリューションだと、MBCS版ですね。
プロジェクトの設定から文字セットを変更していない限りは。

編集 削除
ds  2010-11-19 00:35:16  No: 72051  IP: 192.*.*.*

gakさん、瀬戸っぷさんありがとうございました。
ご指摘の通り、Unコードにて再度ビルドし直したものを利用すると、
コンパイラーとリンカーに怒られずにリンクでき、結果もでました。
これで、2010−09−30日の質問も一挙に解決できました。
ありがとうございました。

ところで、COMの設定で
refclock.h  の内の定義をみると
QueryInterface  ではなく、NonDelegatingQueryInterface  にて  CBaseReferenceClock  は宣言されていますが、QueryInterfaceでもできるのでしょうか。(私の  this  の考え方が間違っているかもわかりません。)
時間がある時にでも、教えてください。
ちなみに、今回はQueryInterfaceでは、実行時エラーが出て、NonDelegatingQueryInterfaceでは問題なく、実行できました。

編集 削除
gak  2010-11-19 17:55:14  No: 72052  IP: 192.*.*.*

> QueryInterface  ではなく、NonDelegatingQueryInterface  にて  CBaseReferenceClock  は宣言されていますが
ルールで CUnknown 派生クラスでは NonDelegatingQueryInterface を使う事になっている、と思っとけば良い。

> QueryInterfaceでもできるのでしょうか
実は QueryInterface も CBaseReferenceClock で定義されている。
DECLARE_IUNKNOWN という記述がそう。
これ#define文で、その中身で QueryInterface(自分のオーナーの QueryInterface を呼ぶだけ)が定義されている。

この QueryInterface を自分で実装してやれば出来無い事は無いだろうけど…
DECLARE_IUNKNOWN 記述部のソースコメントで

/* You must override the (pure virtual) NonDelegatingQueryInterface to return
   interface pointers (using GetInterface) to the interfaces your derived
   class supports (the default implementation only supports IUnknown) */

とMSの人も言っているので言う事を聞いてやろう。

編集 削除