[M1 Mac, Big Sur 11.6.7, clang 13.0.0, no IDE]
前回[C++] 67で作成した関数をsplitクラスにまとめて動的ライブラリdylibにしました。このファイルはプロジェクトとは別に外部クラス用のmylibディレクトリに保管します。dylibファイルはオブジェクトファイルと同等と考えると理解しやすいです。
ライブラリのヘッダファイルをincludeして、クラスをオブジェクト化すると、クラスのメンバ関数として使用することができます。
これで他のプログラムからもsplitクラスが利用可能になりました。
clang++ -dynamiclib -o split.dylib split.cpp -I/mylib/include
#ifndef SPLIT_H
#define SPLIT_H
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <vector>
using std::string; using std::vector;
class split{
public:
// 文字列を文字列delで分割しリスト化する関数
vector<string> splits(string str, char del);
// 分割リストのstart番目からend番目までの要素を結合する関数
string splitjoin(string str, char del, int start, int end);
// 作業ディレクトリを変更する関数
int chCWD(string str, char del, int start, int end);
};
#endif
#include "split.h"
using std::string; using std::vector;
// 文字列を文字列delで分割しリスト化する関数
vector<string> split::splits(string str, char del) {
int first = 0;
int last = str.find_first_of(del);
vector<string> result;
while (first < str.size()) {
string subStr(str, first, last - first);
result.push_back(subStr);
first = last + 1;
last = str.find_first_of(del, first);
if (last == string::npos) {
last = str.size();
}
}
return result;
}
// 分割リストのstart番目からend番目までの要素を結合する関数
string split::splitjoin(string str, char del, int start, int end){
string result2;
vector<string> list = split::splits(str, del);
vector<string> list2;
for (int i = 0; i < list.size(); i++){
if (end < 0){
end += list.size();
}
if (i >= start && i <= end) {
list2.push_back(list[i]);
}
}
for (int i = 0; i< list2.size(); i++){
result2.append(list[i] + del);
}
return result2;
}
// 作業ディレクトリを変更する関数
int split::chCWD(string str, char del, int start, int end){
string new_str = split::splitjoin(str, del, start, end);
int rtn = chdir(new_str.c_str());
return rtn;
}
# includeパス(-I)
INCLUDE = -I./include -I/usr/local/include/FL -I/mylib/include // 実際は絶対パス
# ライブラリ直接パス(-l)
LIBRARY = -lpng16 -lz -ljpeg /mylib/lib/split.dylib
<該当箇所のみ>
#include "split.h"
class split spt;
int main(int argc, char **argv) {
vector<string> l = spt.splits(string(argv[0]), '/');
// 作業ディレクトリを変更
int rtn = spt.chCWD(argv[0], '/', 0, -2);
cout << rtn << endl ;