1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

「序数 X がダイナミックライブラリから見つかりませんでした」というエラーの原因

Last updated at Posted at 2021-02-09

#前提環境
###Aというライブラリがある
A.h:A1という関数を宣言
A.cpp:A1という関数を定義
A.def:A1という関数を「@1」として指定して公開:ここは「序数」の番号
A.lib:コンパイル後作成
A.dll:コンパイル後作成

###BというアプリケーションがライブラリAを使っている
BがA.hを見ている
BがA1という関数を使っている
BがA.libを使用している(関数A1を使用するためにコンパイルする時に使用)
BがA.dllを使用している(関数A1を使用するために実行する時に使用):※ここは重要

#開発の流れ
①Aを製造・修正
②Aをコンパイル
③Bを製造・修正
④Bをコンパイル
⑤A.dllをBの実行フォルダにコピー:※ここは重要
⑥Bを実行して確認

#エラーが発生する経緯
AのA.defで関数A1を「@1」として指定しているため、関数A1と「@1」の対応関係がA.libに反映されている。
BでA1関数を使う時に、A.libを参照しA.libに定義されている対応関係によって、A.dllから「@1」を探す。
すべてのソース・ライブラリ・モジュールは同じバージョンであれば「@1」は確認できるので問題ない。

しかし、上記流れの⑤は漏れたら、この記事のエラーが発生する。

例えば、ライブラリAにA2という関数を追加し、BでA2も使用される。
A.h:A2という関数の宣言を追加
A.cpp:A2という関数の定義を追加
A.def:A2という関数を「@2」として指定:最後にエラーになる番号
A.lib:コンパイル後「@1」と「@2」の2個の対応関係がある
A.dll:コンパイル後A1とA2両方の関数が使える

Bをコンパイルする際、A.hとA.libが参照され、A2という関数が存在することを確認でき、Bをコンパイルしてもエラーにならない。
(コンパイル時、A.hとA.libしか使用しないため、A.hとA.libが正しく参照できる限りBのコンパイルエラーが発生しない)

この後、Aの新しいdllをBの実行フォルダにコピーせずにBを実行すると、Bの実行時エラーが発生する。

原因としては、
①BがライブラリAのA.libからA2という関数が存在することを知っている。
②このため、BがA2を使おうとしている際、A.libの対応関係によってA.dllから「@2」を探す。
③しかし、Bが見えるA.dllは、「@2」がまだ実装されていない古いA.dllであるため、「序数2が見つかりませんでした」というエラーが発生する。

即ち、Bが使用しているA.libのバージョンは、Bが見えるA.dllのバージョンと違う。

解決方法も簡単で、上記開発の流れ⑤を漏れなく再実行すること。
※Aを更新するたびにBの実行フォルダにコピーする必要がある。
 Aのプロジェクトにコピー用のコマンドを指定してもよいし、AとBのモジュールを同じフォルダに作成してもよい。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?