アプリ版:「スタンプのみでお礼する」機能のリリースについて

こんにちは。

C/C++のライブラリファイルについて教えてください。

現在VisualStudio2008 AcademicEditionでライブラリを制作しているのですが質問させてください。
ライブラリを制作するプロジェクトをLibA、そのライブラリを利用して実行ファイルを制作するプロジェクトをProjとします。

LibAでother()関数を利用するのに
#pragma comment ( lib, "other.lib" )とソースコード上に記述しました。
(other.libは他のプロジェクトで自作したスタティックライブラリでLibAと同じフォルダに入っていると仮定します)

ProjでLibAで制作したライブラリを使用するために#pragma comment ( lib, "LibA.lib" )とソースコード上に記述しました。
しかし、other.libが開けませんと怒られてしまいます。

other.libを利用しているのはLibAなのでProj側でother.libを読み込むように強制されるのは面倒臭いのですが、LibA側にother()関数を埋め込むようなことはできないのでしょうか?
LibAを利用するProjでもother.libを要求されないようにするにはどうすればいいでしょうか?

/*
スタティックライブラリを作成するためにLibAをコンパイルする時に#pragma comment ( lib, "other.lib" )の記述が不要というのは知っています。
LibAにその記述を行わなかった場合Projで自分で記述する必要があることも知っています。
*/

現在、私が思いついているのはother.libを作成するプロジェクトのソースコードを引っ張ってきてLibAに入れて一緒にコンパイルするくらいです。


日本語がへたくそでわかりづらいところがあるかとは思いますがよろしくお願いします。

A 回答 (8件)

ダウンロードして



D:\Test\lib\lib_a
D:\Test\lib\lib_b
D:\Test\lib\proj

の構成で試してみました。

(1) lib_b の「追加の依存関係」に $(InputDir)\lib_a.lib と設定されていましたが、

lib_a.lib は

D:\Test\lib\lib_a\Debug
D:\Test\lib\lib_a\Release

に作成されたので、lib_a.lib を

D:\Test\lib\lib_b

にコピーしました。

(2) また、「$(InputDir)\lib_a.lib」だと、

1>------ ビルド開始: プロジェクト: lib_b, 構成: Debug Win32 ------
1>ライブラリを作成しています...
1>LINK : fatal error LNK1181: 入力ファイル 'd:\Test\lib\lib_b\\lib_a.lib' を開けません。
1>ビルドログは "file://d:\Test\lib\lib_b\Debug\BuildLog.htm" に保存されました。
1>lib_b - エラー 1、警告 0
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========

となるので、

$(InputDir)\lib_a.lib

$(InputDir)lib_a.lib

に修正しました。

(3) lib_a も lib_b もソースファイルが main.cpp なので、重複しないように

lib_b の main.cpp を mainb.cpp に変更しました。

(4) Proj はそのまま ビルドしようとすると、

1>------ ビルド開始: プロジェクト: proj, 構成: Debug Win32 ------
1>コンパイルしています...
1>main.cpp
1>マニフェストをリソースにコンパイルしています...
1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>リンクしています...
1>LINK : fatal error LNK1104: ファイル 'lib_b.lib' を開くことができません。
1>ビルドログは "file://d:\Test\lib\proj\Debug\BuildLog.htm" に保存されました。
1>proj - エラー 1、警告 0
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========

となったので、

Proj のプロパティの「リンカ」-「全般」の「追加のライブラリディレクトリ」に

D:\Test\lib\lib_b\Debug

を設定しました。

以上、Proj で lib_a を指定することなくビルドが可能となりました。
    • good
    • 0
この回答へのお礼

ありがとうございます。

先ほど指導の通りにやってみたところ無事成功しました。

原因としては

$(InputDir)\lib_a.lib

$(InputDir)lib_a.lib

ここでした。パスが通ってなかったということっぽいです・・・。
しかし私の環境ではlib_a.libが開けませんというエラーが出なかったので惑わされました・・・

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

お礼日時:2010/11/23 17:47

>other.libが開けませんと


問題がごっちゃになっている気がしますが、
開けないというのは、文字通りの意味であって、
リンクエラーが起こる前に、該当のlibにパスが
通っていないことを表しています。
LibA側とExe側からきちっとパスの通った場所に
other.libがあるかどうかをもう一度確認してみては
いかがでしょう?

>other.libは他のプロジェクトで自作した
>スタティックライブラリでLibAと同じフォルダに入っていると仮定します
少なくとも、私の試した環境で、
上記であれば、正常にリンクできました。

LibAの中で、
#pragma comment ( lib, "testlib01.lib" )
を記述しているならば、リンクするlibはパスが
通っている場所に存在している必要はありますが、
Exe側では上記の記述は要求されないと思います。

================================================
OS:WindowsXP SP3
コンパイラ:VC2008EE
その他:
・ライブラリ定義ファイルあり
・プロジェクトの設定はコード生成をすべて、
 マルチスレッド/マルチスレッドデバッグに変更しておきます。
 #DLLでないことに注意

上記の環境で確認したコードです

=== testlib01 ==================================
-- testlib01.def-----------------
export testlib01
 test01@1

--- testlib01.h-------------------
#ifndef INCLUDE_TEST01LIB_HEADER
#define INCLUDE_TEST01LIB_HEADER
void test01( void );
#endif//INCLUDE_TEST01LIB_HEADER

--- testlib01.c-------------------
#include <stdio.h>
#include "testlib01.h"
void test01( void )
{
 printf("testlib01\n");
}

=== testlib02====================================
---testlib.def-------------------------
export testlib02
 test02@1

---testlib02.h-------------------------
#ifndef INCLUDE_TEST02_HEADER
#define INCLUDE_TEST02_HEADER
void test02( void );
#endif//INCLUDE_TEST02_HEADER

--- testlib02.c-------------------------
#include "testlib01.h"
#include "testlib02.h"
#pragma comment ( lib, "testlib01.lib" )
void test02( void )
{
 test01();
}

=== testexe =================================
#include "testlib02.h"
#pragma comment ( lib, "testlib02.lib" )
int main( void )
{
 test02();
 return 0;
}

※全角スペースは半角スペースに直してください。

Exeコンパイル時のフォルダ構造は以下の通り
+testexe
 +Debug
 |+testexe.exe
 +testexe
 |+Debug
 |+testexe.vcproj
 |+testlib01.lib
 |+testlib02.lib
 |+testlib02.h
 |+testexe.c
 +testexe.sln

ライブラリのパスを整備すればもっときれいになりますが、
とりあえずの環境だったのでそのあたりは割愛しています。
    • good
    • 0
この回答へのお礼

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

問題がごっちゃになってしまってすみません。

現状ではtestexeフォルダにtest01.libを入れないでtest02.libの中にtest01.libの中身を埋め込む方法を知りたいと考えています。

今回の問題でいえば、ProjのフォルダにLibA.libとother.libを入れれば動作するのはわかっているのですが、ProjからはLibA.libを通してでしかother.lib内の関数を利用していないのでother.libを要求されるのは面倒臭いと思ったのです。
そこでLibAが使用しているother.libに入っている関数をLibA.libが一緒にライブラリとして固めてくれればProjフォルダにother.libを入れる必要がなくなる、と考えています。
(いままでの質問ではすべての情報を伝えきれていなかったようです・・・。申し訳ありませんでした。)

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

お礼日時:2010/11/22 22:15

どうしてでしょね・・・。


試しに

other.lib
============================================================
#include "stdafx.h"

int OtherFunc( int a, int b )
{
return( a + b );
}
============================================================


LibA.lib
============================================================
#include "stdafx.h"

extern int OtherFunc( int a, int b );

int LibAFunc( int a, int b )
{
return( OtherFunc( a, b ) );
}
============================================================


Proj.exe
============================================================
#include "stdafx.h"

extern int LibAFunc( int a, int b );

int _tmain(int argc, _TCHAR* argv[])
{
int i = LibAFunc( 100, 200 );
return 0;
}
============================================================

というのを作って、ビルドしてみましたが、
LibA のプロパティの「追加の依存関係」で other.lib を追加していなかった場合は Proj.exe のビルドのとき、「OtherFunc が見つかりません」という内容のエラーになりましたが、
LibA のプロパティの「追加の依存関係」で other.lib を追加してやると、Proj.exe のビルドのとき、エラーがでなくなりました。
念のため、LIB.EXE で、LIB LIBA.LIB /LIST を実行してみると、ちゃんと、other.obj が入ってましたし、「追加の依存関係」に追加する方法で間違いないようですよ。

Proj の中で other.lib の関数を使用しているってコトはないですよね?
それとか、「追加の依存関係」と間違って「追加のライブラリディレクトリ」の方に追加してしまっているとか・・・。
    • good
    • 0
この回答へのお礼

ありがとうございます。

返信遅れてしまって申し訳ありません。
お二方にご教授していただいた方法を試してみたのですが、やはりリンクエラーが発生してしまっています。

何か決定的な勘違いをしているかもしれないので今回のテストのために制作したプロジェクト3つをアップローダ―にアップいたしました。
お手数をおかけしますがダウンロードして何が問題なのか確かめていただきたいと思います。

http://www1.axfc.net/uploader/Sc/so/176106
Download Password : lib

よろしくお願いします。

お礼日時:2010/11/22 22:06

>今確認してみたところ、スタティックライブラリのプロジェクトの設定では追加の依存ファイルという項目がなく、リンカオプションで指定することはできないようです。



LibA のプロジェクトのプロパティ

構成プロパティ

ライブラリアン

に「追加の依存関係」という項目がありませんか?

ここに other.lib のパスを記述すれば良いと思います。
    • good
    • 0
この回答へのお礼

ありがとうございます。

先ほど確認したところ確かにライブラリアンの中に追加の依存関係というものはありました。
しかし、other.libを指定してコンパイルしProjにてLibAと一緒にコンパイルしたところother.lib内に入っている関数のリンクエラーが出てしまったので、この方法では関数は埋め込まれないようです。

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

お礼日時:2010/11/21 23:59

#3 のお礼について



ふーん、そうなんですね。

では、#pragma comment を使わずに、
LibA のリンカオプションで other.lib を指定したらどうでしょうか?
    • good
    • 0
この回答へのお礼

ありがとうございます。

今確認してみたところ、スタティックライブラリのプロジェクトの設定では追加の依存ファイルという項目がなく、リンカオプションで指定することはできないようです。
(私が勘違いしているようでしたら申し訳ございません)

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

お礼日時:2010/11/21 21:41

> other.libが開けませんと怒られてしまいます。



これって、LibA.lib のビルド時に出ていませんか?
    • good
    • 0
この回答へのお礼

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

LibA.libのビルド時には実はother.libは必要ないのでProjのコンパイル時に出ています。
(LibAのソースファイルに#pragma comment ( lib, "other.lib" )と記述しても、LibAのコンパイル時はファイルを参照しにいかないようなのでなくても大丈夫なようです。ただしLibA.libを使用するプロジェクト(実行ファイルを生成するようなプロジェクト)では要求されます。)
(なぜ必要ではないのかはよくわかりませんが・・・)

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

お礼日時:2010/11/21 17:42

ライブラリをくっつければいいのかな。



lib /OUT:hoge.lib LibA.lib other.lib

参考URL:http://msdn.microsoft.com/ja-jp/library/e17b885t …
    • good
    • 0
この回答へのお礼

ありがとうございます。

ツールを使用してくっつけてしまう方法ですね。
この方法は初めて見たのですが視野に入れたいと思います。

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

お礼日時:2010/11/21 16:18

>ProjでLibAで制作したライブラリを使用するために#pragma comment ( lib, "LibA.lib" )とソースコード上に記述しました。


>しかし、other.libが開けませんと怒られてしまいます。

Projのプロジェクトの設定で、ライブラリの検索パスにLibAが入っていますか?
確か、設定が必要だったかと思いますが…。
# リンカオプションに「追加のライブラリ ディレクトリ」というのがあるかと。

この回答への補足

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

LibAのフォルダからLibA.libをコピーアンドペーストでProjのフォルダにコピーして使用できるようにしたいと思っています。
ですのでLibAのフォルダにパスを通すというのは今回はなしの方向でお願いします。

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

補足日時:2010/11/21 16:14
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!