Visual StudioでDLLを生成して別のプロジェクトから使ってみた
いろんなサイトを見てみてましたが、MSDNの下記サイトの解説が一番シンプルで分かりやすく感じました。
チュートリアル: ダイナミック リンク ライブラリの作成と使用 (C++)
サイトの解説通り行うことで、1つのソリューションにDLLのプロジェクトとDLLを使うプロジェクトの2つを追加し、DLLを使うプロジェクトからDLLの関数を呼び出すことに成功しました。 DLLのプロジェクトの場合、「プロジェクト名_EXPORTS」がプリプロセッサの定義に追加されることも上のサイトに記載されています。
次は、配布されているDLLの使い方について調べてみようと思います。
boost::serializationを使ってみた
C++でシリアライズを使ったコードを書いたことがなかったので、勉強のためにboost::serializationを使ってみました。
環境構築
Macを使っており、boostはbrew で brew install boost
で入れることができました(入れたの自体は大分前です)。
~/.bash_profile に以下のようにインクルードとライブラリのパスを追加しました。
export CPATH="/usr/local/Cellar/boost/1.67.0_1/include":$CPATH export LIBRARY_PATH="/usr/local/Cellar/boost/1.67.0_1/lib":$LIBRARY_PATH
ソースコード
#include <iostream> #include <string> #include <fstream> #include <boost/serialization/serialization.hpp> #include <boost/serialization/string.hpp> #include <boost/archive/binary_oarchive.hpp> #include <boost/archive/binary_iarchive.hpp> #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> using namespace std; class Human { public: Human() : m_name("") , m_age(0) {} Human(string name, int age) : m_name(name) , m_age(age) {} public: void Print() { cout << "name: " << m_name << endl; cout << "age : " << m_age << endl; } private: string m_name; int m_age; friend class boost::serialization::access; template<typename Archive> void serialize(Archive& ar, const unsigned int version) { ar & m_name; ar & m_age; } }; const char* TEXT_FILE_NAME = "text_output.txt"; const char* BINARY_FILE_NAME = "binary_output"; int main() { // シリアライズして保存 { Human human("橘美也", 16); // テキストで保存 { ofstream text_ofs(TEXT_FILE_NAME); boost::archive::text_oarchive text_oa(text_ofs); text_oa << human; text_ofs.close(); } // バイナリで保存 { ofstream binary_ofs(BINARY_FILE_NAME); boost::archive::binary_oarchive binary_oa(binary_ofs); binary_oa << human; binary_ofs.close(); } } // 読み込みと出力 { // テキストを読み込み { Human text_human; ifstream text_ifs(TEXT_FILE_NAME); boost::archive::text_iarchive text_ia(text_ifs); text_ia >> text_human; text_ifs.close(); cout << "テキストを読み込み" << endl; text_human.Print(); } // バイナリを読み込み { Human binary_human; ifstream binary_ifs(BINARY_FILE_NAME); boost::archive::binary_iarchive binary_ia(binary_ifs); binary_ia >> binary_human; binary_ifs.close(); cout << endl; cout << "バイナリを読み込み" << endl; binary_human.Print(); } } return 0; }
ビルド
clang++ boost_seria.cpp -lboost_serialization
出力結果
テキストを読み込み name: 橘美也 age : 16 バイナリを読み込み name: 橘美也 age : 16
出力ファイル
text_output.txt
22 serialization::archive 16 0 0 9 橘美也 16
所感
特に苦労することもなく、シリアライズを行うことができました。
brewとboostとインターネットは偉大ですね。
疑問点は下記の項目です。また調べます。
- 同じインスタンスを出力したバイナリファイル(サイズ66byte)よりテキストファイル(サイズ44byte)の方が容量が小さい(テキスト > バイナリだと思っていたけどそうではない?)
- text_output.txtの22とかの数値の意味
- ビルド時の
-lboost_serialization
みたいなライブラリ名をどうやって見つけるのか。どのヘッダファイルがどのライブラリに対応しているのかを調べる方法 - /usr/local/Cellar/とは
参考文献
boost::serializationの使い方
boost::serialization - C++でゲームプログラミング
C++でLuaを使ってみた
luaはMacでbrewがあればbrew install lua
で入ります。環境構築が非常に楽で良いですね。
注意点としてはCだと<lua.h>、C++だと<lua.hpp>をインクルードしないとビルドできません。
main.cpp
#include <lua.hpp> #include <lauxlib.h> #include <lualib.h> int main() { lua_State *lua = luaL_newstate(); luaL_openlibs(lua); luaL_dofile(lua, "test.lua"); return 0; }
test.lua
print("Hello ルア") print(math.sqrt(4));
ビルド〜実行
[nemumitakamaru lua_test]$ ls main.cpp test.lua [nemumitakamaru lua_test]$ clang++ main.cpp -llua [nemumitakamaru lua_test]$ ./a.out Hello ルア 2.0
参考文献
ld: library not found for -lhogeと出て静的ライブラリがリンクできない
静的ライブラリについて勉強するぞ!となり、グーグル先生で調べて出てきた以下のページを見ながらMacで静的ライブラリを作ってリンクして実行ファイルを作るまでを試してみました。
しかし、ライブラリをリンクする段階で詰まりました。
出たエラー文は下記です。
[nemumitakamaru libtest]$ clang main.c -lstatic ld: library not found for -lstatic clang: error: linker command failed with exit code 1 (use -v to see invocation)
libstatic.a
が見つからないらしいです。
ちなみにls
するとこんな感じです。
[nemumitakamaru libtest]$ ls libstatic.a main.c static_library.c static_library.o
ソースコードとlibstatic.a
が同じフォルダに存在するだけでは駄目ってことなんですかね。
再度グーグル先生で調べてみて、↓のサイトを読むと、ライブラリのパスを指定するには-L
を付ければ良いとわかりました。
qiita.com
というわけで、-L.
をつけて静的ライブラリが存在するパスをカレントディレクトに指定してみましたところ、ちゃんとリンクに成功しました。
[nemumitakamaru libtest]$ clang main.c -L. -lstatic [nemumitakamaru libtest]$ ./a.out This is a static library.
カレントディレクトのライブラリを自動的に検索してくれる設定とかがあるんですかね?
jsoncppを使ってみた
C++でjsonを扱うコードをろくに書いたことがなくて知識的に不安だったので、ぐーぐる先生で調べて出てきたjsoncppというossを使ってjsonのファイルをパースして表示してみました。 github.com
内容
test.json
{"name" : "nemumitakamaru","email" : "nemumitakamaru@gmail.com","number":1}
#include <iostream> #include <fstream> #include <string> #include <json/json.h> using namespace std; int main() { // ファイルの読み込み ifstream infile; infile.open("test.json"); if(!infile) { exit(1); } string testJson; getline(infile, testJson); infile.close(); // jsonをパース Json::Reader reader; Json::Value value; reader.parse(testJson, value); // 表示 cout << value["name"].asString() << endl; cout << value["email"].asString() << endl; cout << value["number"] << endl; return 0; }
出力結果
nemumitakamaru nemumitakamaru@gmail.com 1
という感じでコードでjsoncppを使う分には簡単にできました。
それ以前の問題で、libファイルを作って、VS2015でincludeのパスを通して、libを登録してビルドするという段階で知識がなくて苦戦しました。それに関しては調査してまたブログにまとめようと思います。
あと、基本的なファイルストリームのifstreamの使い方をよく分かっていないことも分かったので、それもまた今度調査してみようと思います。
ファイル読み込みに失敗しているかを判定するために、infile.bad()
やinfile.fail()
等色々あるっぽいです。