Cで作成されたLIBをMFCで使用したいがLNK2019が出る – プログラミング – Home

Cで作成されたLIBをMFCで使用した...
 
通知
すべてクリア

[解決済] Cで作成されたLIBをMFCで使用したいがLNK2019が出る


ブヒブヒ
 ブヒブヒ
(@ブヒブヒ)
ゲスト
結合: 15年前
投稿: 26
Topic starter  

いつもお世話になっております。
ブヒブヒです。

開発環境
WinXP Pro SP3
VC2005 SP1 MFC

VC++6.0でCとWin32APIで作成されたプログラムで
使用していたスタティックライブラリを
上記開発環境のプロジェクトで使用したいと考えております。
(ある計測機器をコントロールするためのライブラリで
ソースはありません。サポートもありません。)

ヘッダーファイル内の関数定義を
extern C { }で囲い、
ビルドが成功するところまで出来たのですが、
ヘッダー内の関数を呼び出すとLNK2019エラーが出てしまいます。

下記のようなソースとなっております。
AAA.hファイル内
-----------------------------
extern C
{
extern int BBB(...);
extern int CCC(...);
}
-----------------------------

XXX.cppファイル内
-----------------------------
#include AAA.h
#pragma comment( lib, AAA.lib )

// いろいろ宣言があって

void CXXXDlg::OnBnClickedButton1()
{
BBB(...);
}
-----------------------------

エラーは下記のようになっております。
LNK2019: 未解決の外部シンボル _BBB が
関数 public: void __thiscall CXXXDlg::OnBnClickedButton1(void)
(?OnBnClickedButton1@CXXXDlg@@QAEXXZ) で参照されました。

OnBnClickedButton1()内のBBB()関数をコメントアウトすると
問題なくビルドが成功します。

どのようにしたらBBB()関数を使用できるのでしょうか。
大変申し訳ありませんが
よろしくお願いいたします。
ブヒブヒ


引用未解決
トピックタグ
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

当該の「スタティックライブラリ」は、
関数「BBB()」を含む他のライブラリとリンクしてませんか?


返信引用
wood
 wood
(@wood)
ゲスト
結合: 23年前
投稿: 895
 

extern int BBB(...);
extern int CCC(...);
この2つの関数は外部参照として宣言されていることから
プロジェクトにリンクするライブラリ(LIB)はコンパイルオプションや
リンクオプションでライブラリ名はパスを含めきちんと追加されてますか?


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

リンカが正しく aaa.lib を見つけているかをチェック
aaa.lib 中の export symbol が _BBB であること (_BBB@0 等でないこと) を確認
dumpbin /exports aaa.lib

逆に _BBB@0 等であれば extern のやりかたが間違っているわけでそっちを修正


返信引用
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

少し細かく解説

> extern C
> {
> extern int BBB(...);
> extern int CCC(...);
> }
ということは、BBB(), CCC()関数の実体はここにはなく、参照のみだという
ことです。つまり、別の場所に実体が必要ということね。
そこはOK?

そして、
> LNK2019: 未解決の外部シンボル _BBB が
> 関数 public: void __thiscall CXXXDlg::OnBnClickedButton1(void)
> (?OnBnClickedButton1@CXXXDlg@@QAEXXZ) で参照されました。
は、BBB()関数の実体が見つからないという話。

なので、AAA.lib 内に BBB()関数 がいるか確認してください。

で、確認方法が、
tetrapodさんの書かれているものになるのかな、たぶん。


返信引用
ブヒブヒ
 ブヒブヒ
(@ブヒブヒ)
ゲスト
結合: 15年前
投稿: 26
Topic starter  

皆様
ありがとうございます。

お返事が遅れてしまい、申し訳ありません。
別のことに時間を取られていました。

tetrapodさんの方法でAAA.lib内を確認してみます。

よろしくお願いいたします。
ブヒブヒ


返信引用
ブヒブヒ
 ブヒブヒ
(@ブヒブヒ)
ゲスト
結合: 15年前
投稿: 26
Topic starter  

皆様
お世話になっております。
ブヒブヒです。

dumpbin /export AAA.lib
を試してみました。

?TestFunc@@~
?TestCheck@@~
というのが表示されたので、
C言語で作成されたという条件が間違っておりました。
ご迷惑をおかけして申し訳ありませんでした。

しかし、AAA.hファイルに定義されている
BBB()やCCC()が出てきませんでした。

ライブラリファイルはAAA.libのみで他にはありません。
dumpbin /exportで表示されない関数もあるのでしょうか?

そして現在、AAA.hのexturn Cを削除して
ビルドしようとしているのですが、

AAA.lib(YYY_1.obj) : error LNK2019: 未解決の外部シンボル
public: void __thiscall CString::SetAt(int,char)
(?SetAt@CString@@QAEXHD@Z) が「AAA.lib内にある関数名」で参照されました。

AAA.lib(YYY_2.obj) : error LNK2001: 外部シンボル
"public: void __thiscall CString::SetAt(int,char)
(?SetAt@CString@@QAEXHD@Z) は未解決です。

というようにCString::~というエラーが30件以上、出てきました。

このエラーはどのようにしたら解消できるのでしょうか?
質問内容が件名から変わってしまいましたが
教えていただけないでしょうか。
よろしくお願いいたします。
ブヒブヒ


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

エラーメッセージが主張している、見つからないエラーになっているシンボルは
public: void __thiscall CString::SetAt(int, char) であるわけだ。
これは Visual Studio 6.0 のころの MFC 4.2 (MBCS) だよ。
ウチの手元の VS6.0 のライブラリディレクトリ上で dumpbin /all mfc42.lib したら
このシンボルがきっちり見つかった。

VS6.0 付属の MFC4.2 と VS2005 付属の MFC8 はバイナリレベルでは非互換なので
リンクエラーになって当然だと思われる。

ということは・・・簡単な解決策は無い・・・なぁ。VS6.0 はあるのかな?ならば
VS2005 をあきらめてプロジェクト全体を VS6.0 でコンパイルするか
エラーになってるのが CString 関連だけなら自分で Wrapper 作るか
MFC4.2 の CString 系ソースを持ってきて VS2005 でコンパイルするか
当該ライブラリのソースをなんとしてでもげっちゅして VS2005 でコンパイルするか
その辺かな・・・


返信引用
maru
 maru
(@maru)
ゲスト
結合: 17年前
投稿: 358
 

VC6でDLLを作ってAAA.libをリンクする。
VC2005ではそのDLLを使用するってのは? つまりBBB(), CCC()のラッパー。
という手はどうですか?

関数名の衝突を避けるために、DLLでexportする関数名は変更する必要があるけど。


返信引用
ブヒブヒ
 ブヒブヒ
(@ブヒブヒ)
ゲスト
結合: 15年前
投稿: 26
Topic starter  

tetrapodさん、maruさん
お返事ありがとうございます。

とりあえずVC6.0 MFCで動くようにしようと思い、
VC++6.0 SP6 MFCでプロジェクトを作成し、
ビルドする段階まできました。

リリースビルドは問題なくできるのですが、
デバッグビルドにすると下記のようなエラーが
たくさん出てしまいます。

libc.lib(crt0dat.obj) : error LNK2005: __cinit はすでに
libcmtd.lib(crt0dat.obj) で定義されています

libc.lib(crt0dat.obj) : error LNK2005: _exit はすでに
libcmtd.lib(crt0dat.obj) で定義されています

このエラーはどうやって解消するのでしょうか。
度々申し訳ありませんが
教えていただけないでしょうか。
よろしくお願いいたします。
ブヒブヒ

PS
Exe単体でなければいけないToolはVC6.0で。
機能提供や迅速なGUI作成が必要な場合はラッピングしたDLLで。
という方針で行きたいと思います。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

それは FAQ なんで調べて味噌。まあ端的には
「デバッグモードにはデバッグモード用のライブラリをリンクする必要がある」
「リリースモードにはリリースモード用のライブラリをリンクする必要がある」
「デバッグとリリースを混在させてはダメ」
ということ。
当該計測機器ライブラリのデバッグモード用があるかどうか調べて、
・デバッグモードにはデバッグモードのライブラリを使う、か
・デバッグモードをあきらめてリリースモードでデバッグする、か
どっちか。

もうひとつ、スレッドモデルが違うとダメ。
libcmtd は LIBrary for C of Multi Thread - Debug の意味
libc は LIBrary for C (single thread without debug) の意味
やはり同じく、当該計測機器ライブラリのスレッドモデルを調べて、
・プロジェクトのコンパイルオプションをライブラリにあわせる、か
・プロジェクトのコンパイルオプションに適合するライブラリを使う、か
どっちか。

なので Visual C 用のライブラリは [MT/ST]+[Debug/Release] で4種類あるのが普通
気の利いたライブラリメーカなら4種類とも用意しているはず。
aaa.lib + aaamt.lib + aaad.lib + aaamtd.lib のように。
(順に、シングルスレッドリリース、マルチスレッドリリース、
シングルスレッドデバッグ、マルチスレッドデバッグ、用のライブラリ)
まずはその辺探してみるべし(俺たち読者には状況がわからんからな)

# 実はさらに STATIC/DYNAMIC 違いによって8種類あったりするのだが...


返信引用
ブヒブヒ
 ブヒブヒ
(@ブヒブヒ)
ゲスト
結合: 15年前
投稿: 26
Topic starter  

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

申し訳ありません。
記述し忘れていたのですが
デバッグ用ライブラリとリリース用ライブラリの2つあります。
(正確にはデバッグとリリース用のライブラリ、計2つと
関数の簡易説明ドキュメント、現在使用しているCとWin32APIで作成された
ツールとプロジェクトを引き継ぎました)

プロジェクトの設定ダイアログの
C/C++のコード生成や
リンクのインプットで無視するライブラリの設定を
変更して試してみた結果。

リリースビルドでは
C/C++のコード生成でシングルスレッドでもマルチスレッドでも
ビルドが成功しました。

デバッグビルドでは
C/C++のコード生成でシングルスレッドでビルド成功。
マルチスレッドでlibcmt,libcpmtd,libcのライブラリを無視にすると
ビルドが成功しました。

これから装置をコントロールできるか確認します。

このあたりの設定は今まで全くいじったことがないので助かりました。
ありがとうございました。
ヘッポコプログラマ@ブヒブヒ


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

> マルチスレッドでlibcmt,libcpmtd,libcのライブラリを無視にすると
> ビルドが成功しました。
ビルドが成功しても *正しく動かない* からダメ。
伊達や酔狂で警告が出ているんぢゃないんだから無視しちゃ/させちゃダメ。


返信引用
ブヒブヒ
 ブヒブヒ
(@ブヒブヒ)
ゲスト
結合: 15年前
投稿: 26
Topic starter  

tetrapodさん
ありがとうございます。
気をつけます。
ブヒブヒ


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました