[Obj-C] 01 コンソールアプリのMakefile

[M1 Mac, Big Sur 11.6.5, no Xcode]

Objective-CでのmacOSアプリ製作に着手しました。知識ゼロなので一から学んでいきます。GUIのXcodeは極力使わないようにします。

まずはコンソールアプリのMakefileを作成してみました。C++のテンプレを流用しています。今のところソースコードの内容についてはあまり理解していません。

次はWindowのあるアプリを作成します。

# コンパイラ
COMPILER = clang
DEBUG = -g

# オプション
CFLAGS =
LDFLAGS = -framework Cocoa

# includeパス(-I)
INCLUDE = -I.

# ソースファイル
SRCDIR = .
SRCS = $(SRCDIR)/test.m

# オブジェクトファイル
OBJDIR = .
OBJS = $(OBJDIR)/test.o

# 実行ファイル
TARGETDIR = .
TARGET = test

# コンパイル
$(OBJDIR)/test.o: $(SRCDIR)/test.m
	$(COMPILER) $(INCLUDE) $(DEBUG) -o $@ -c $<

# ビルド
$(TARGET):$(OBJS)
	$(COMPILER) -o $(TARGETDIR)/$@ $(OBJS) $(LDFLAGS)

# ファイル削除&ビルド
.PHONY:all
all: clean $(TARGET)

# ファイル削除
.PHONY:clean
clean:
	rm -rf $(OBJS) $(TARGETDIR)/$(TARGET)
#import "test.h"
 
@implementation AppDelegate
- (id) init {
    [super init];
    return self;
}
- (void) applicationDidFinishLaunching:(NSNotification *)aNotification{
    // アクティブ化
    [NSApp activateIgnoringOtherApps:YES];
}
@end
 
@implementation AppMenu
- (id) init {
    [super init];
    id item_app = [[NSMenuItem new] autorelease];
    [self addItem:item_app];
    id menu_app = [[NSMenu new] autorelease];
    [item_app setSubmenu:menu_app];
    id item_quit = [[NSMenuItem new] autorelease];
    [item_quit initWithTitle:@"Quit App" action:@selector(terminate:) keyEquivalent:@"q"];
    [menu_app addItem:item_quit];
    return self;
}
@end
 
int main(int argc, char *argv[]) {
    // メモリ管理
    [NSAutoreleasePool new];
    // NSApp作成
    [NSApplication sharedApplication];
    // setActivationPolicy
    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
    // メニュー設定
    id main_menu = [[AppMenu new] autorelease];
    [NSApp setMainMenu:main_menu];
    // Delegate
    id delegate = [[AppDelegate new] autorelease];
    [NSApp setDelegate:delegate];
    // メインループ
    [NSApp run];

    return 0;
}
#import <Cocoa/Cocoa.h>
 
@interface AppMenu : NSMenu
@end
 
@interface AppDelegate : NSObject<NSApplicationDelegate>
@end

参考サイト

[C++] 63 FLTK : xlsx変換アプリ / appファイルの不具合3

[M1 Mac, Big Sur 11.6.5, Python 3.10.4]

デバッグ用コードを走らせ、実行内容をチェックしました。

sysPath 6個に対してGetPath 3個となっており、pathを追加できていないだけでなく数も合っていません。

つまりsys.pathとPython/C APIのmodule search pathは一致しないということが判明しました。集合で表現するとmodule search path ⊂ sys.pathになります。

module search pathの設定がPy_SetPath()やPYTHONPATH以外の方法でできないとなると、これ以上の追究は厳しくなります。

#define PY_SSIZE_T_CLEAN
#include "process.h"
#include </Library/Frameworks/Python.framework/Versions/3.10/include/python3.10/Python.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>

#define PATH L"/Python/library/python_module:/Library/Frameworks/Python.framework/Versions/3.10/lib/python310.zip:/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10:/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/lib-dynload"

using std::string;

string XlsxToList(const char* path) {
    // Py_SetPath(PATH);

    Py_Initialize();
	
	// PyObject* sysPath = PySys_GetObject("path");
	PyObject* sys = PyImport_ImportModule( "sys" );
	PyObject* sysPath = PyObject_GetAttrString( sys, "path" );
	std::cout << "追加前path数 " << PyList_Size(sysPath) << std::endl;
	std::cout << "PyObject* sysPath通過" << std::endl;

	PyObject* module_path = PyUnicode_FromString("/Python/library/python_module");
	std::cout << "PyObject* module_path通過" << std::endl;
	
	int append_bool = PyList_Append(sysPath, module_path);
	std::cout << "PyList_Append通過" << std::endl;
	std::cout << append_bool << std::endl;

	std::cout << "追加後path数 " << PyList_Size(sysPath) << std::endl;

	// 	module search pathを出力し、パスの内容と個数を確認
	std::wcout << Py_GetPath() << std::endl;

    // pyファイルのモジュール化
    PyObject* myModule = PyImport_ImportModule((char*)"test");
	std::cout << "myModule通過" << std::endl;

	const char* function = "xlsx_to_list";
	int attr_bool = PyObject_HasAttrString(myModule,function);
	std::cout << "attr_bool通過" << std::endl;
	std::cout << attr_bool << std::endl;
    
    // pyファイル内の関数を指定 ここでエラー発生
    PyObject* myFunction = PyObject_GetAttrString(myModule,function);
    
    // 関数の引数を設定
    PyObject* args = PyTuple_Pack(1,PyUnicode_FromString(path));
    
    // 関数を実行し戻り値をPyObjectとして取得
    PyObject* myResult = PyObject_CallObject(myFunction,args);
    
    
    // PyObjectをconst char*に変換
    const char* result = PyUnicode_AsUTF8(myResult);

    std::cout << result << std::endl;

    return result;

    Py_FinalizeEx();
    
}
--------------------------------------------------
出力
--------------------------------------------------
追加前path数 5
PyObject* sysPath通過
PyObject* module_path通過
PyList_Append通過
0
追加後path数 6
/Library/Frameworks/Python.framework/Versions/3.10/lib/python310.zip:/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10:/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/lib-dynload
myModule通過
attr_bool通過
0
Segmentation fault: 11