ねむみ高まる

文章力がないので、文章を書く練習をしています。

Visual StudioでDLLを生成して別のプロジェクトから使ってみた

いろんなサイトを見てみてましたが、MSDNの下記サイトの解説が一番シンプルで分かりやすく感じました。
チュートリアル: ダイナミック リンク ライブラリの作成と使用 (C++)

サイトの解説通り行うことで、1つのソリューションにDLLのプロジェクトとDLLを使うプロジェクトの2つを追加し、DLLを使うプロジェクトからDLLの関数を呼び出すことに成功しました。 DLLのプロジェクトの場合、「プロジェクト名_EXPORTS」がプリプロセッサの定義に追加されることも上のサイトに記載されています。

次は、配布されているDLLの使い方について調べてみようと思います。

boost::serializationを使ってみた

C++シリアライズを使ったコードを書いたことがなかったので、勉強のためにboost::serializationを使ってみました。

環境構築

Macを使っており、boostはbrewbrew 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を使ってみた

luaMacbrewがあれば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

参考文献

msyksphinz.hatenablog.com

ld: library not found for -lhogeと出て静的ライブラリがリンクできない

静的ライブラリについて勉強するぞ!となり、グーグル先生で調べて出てきた以下のページを見ながらMacで静的ライブラリを作ってリンクして実行ファイルを作るまでを試してみました。

qiita.com

しかし、ライブラリをリンクする段階で詰まりました。

出たエラー文は下記です。

[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}


C++ソースコード

#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()等色々あるっぽいです。

参考文献

kaworu.jpn.org

qiita.com

固定電話(IP電話/BBフォン)でTwitterのアカウントロックの解除ができました

自分がぐーぐる先生で調べたときに、特に固定電話(IP電話/BBフォン)で解除できたという話が出てこなかったので書いておきます。

経緯

Twitterのアカウントを作って、2アカウントフォローして、2つつぶやいたらその瞬間にアカウントにロックがかかりました。何にも変なことしてないのに厳しすぎでは…

f:id:nemumitakamaru:20181015230400p:plain

携帯電話番号を登録してSMS経由で認証すれば良いって話なのですが、普段使いの番号は知り合いが自分の連絡先をTwitterに登録しているっぽく、前に垢を作ったときにおすすめユーザーに表示されたことがあったので絶対に避けたい感じでした。また、Twitterの異議申し立てのフォームから不正はしていないと連絡をしても、「電話番号を入れてね!」の自動返信の文章のメールが数秒で返ってきて、全く持って駄目でした。

そこで、Twitterの検索で「twitter 固定電話 認証」で調べてみると、固定電話でアカウントのロックを解除できた!とつぶやいている方が数名見受けられました。Twitterのロック解除のページを見た感じSMSしか対応してなさそうなのにどうやって?と思ったのですが、電話がきたと書いている方がいました。なるほどと思い、ソフトバンク光と契約したときにオプションでついてきたけど全く使ってなかった、「BBフォン」でいけるのでは?となったので、その日のうちに電話機をアマゾン注文し、アカウントロックの解除を試してみた次第です。

手順

1:電話番号を追加の画面でIP電話の番号を入力→コードを送信

2:コードが届きませんをクリック f:id:nemumitakamaru:20181015225945p:plain

3:自動音声通知で受け取るをクリック f:id:nemumitakamaru:20181015230202p:plain

4:電話で6桁くらいの認証コードが来る→入力

と、こういう感じでTwitterのアカウントのロックの解除をすることができました。
無事Twitterライフを送れそうなので、何とかフォロワー0人から脱却できるように有意義なことをつぶやけるようにがんばります…

レビューは匿名可にして欲しい

仕事として会社のよく知らない方が作った、仕様や制作の流れ等を全く知らない成果物に対してレビューを実名付きで書くことがあります。
が、うまいこと書くことができません…

今と違う部署だったときにレビューを受ける側の偉い人がレビューに対してぶちぎれていることを見たこともあり、正直に書いて何か言われることが怖いです。
というわけで、レビューを募集するなら匿名可にして欲しいという気持ちでいっぱいです。
まあ、匿名にしたらしたで、責任感がなくなって全体的なレビューの質が落ちてしまいそうな感じもありますが。

どうするのが良いんでしょうかね。