4

objc_msgSend を使用して Objective C コードを使用して、Objective C ランタイムを手動で実行できることはわかっていますが、このコードを実行すると、NSString (使用したことはありませんが) や他の未使用のクラスを参照するエラーが発生します。 .

xcode からのエラー

ここに画像の説明を入力

その上に、「模倣」しようとしている目的の C コード (コメント アウト) があります。

#include <Foundation/Foundation.h> /*Added suggestion by answer, same errors*/
#include <AppKit/AppKit.h>

int main()
{
// convert objective c into c code
/*
    NSAlert *alert = [[NSAlert alloc] init];
    [alert setAlertStyle:NSInformationalAlertStyle];
    [alert setMessageText:@"Hello World"];
    [alert setInformativeText:@"Hello World"];
    [alert runModal];
*/
    id alert = objc_msgSend(objc_msgSend(objc_getClass("NSAlert"), sel_registerName("alloc")), sel_registerName("init"));
    objc_msgSend(alert, sel_getUid("setAlertStyle:"), NSInformationalAlertStyle);
    objc_msgSend(alert, sel_getUid("setMessageText:"), CFSTR("Hello World!"));
    objc_msgSend(alert, sel_getUid("setInformativeText:"), CFSTR("Hello World!"));
    objc_msgSend(alert, sel_getUid("runModal"));
}
4

1 に答える 1

5

一部のインポートがありません。

objc_msgSendで宣言されてい<objc/message.h>ます。

objc_getClassで宣言されてい<objc/runtime.h>ます。

sel_getUidsel_registerName宣言されてい<objc/objc.h>ます。

<objc/objc.h>が によってすでにインポートされていることを考えると<objc/runtime.h>、後者を > とともにインポートするだけ<objc/message.hで十分です。

次の例でテストしましたが、期待どおりに動作します

#include <CoreFoundation/CoreFoundation.h> // Needed for CFSTR
#include <objc/runtime.h>
#include <objc/message.h>

int main(int argc, char *argv[]) {
    id alert = (id (*)(id, SEL))objc_msgSend((id (*)(id, SEL))objc_msgSend(objc_getClass("NSAlert"), sel_registerName("alloc")), sel_registerName("init"));
    (void (*)(id, SEL, int))objc_msgSend(alert, sel_getUid("setAlertStyle:"), 1); // NSInformationalAlertStyle is defined in AppKit, so let's just use 1
    (void (*)(id, SEL, id))objc_msgSend(alert, sel_getUid("setMessageText:"), CFSTR("Hello World!"));
    (void (*)(id, SEL, id))objc_msgSend(alert, sel_getUid("setInformativeText:"), CFSTR("Hello World!"));
    (int (*)(id, SEL))objc_msgSend(alert, sel_getUid("runModal"));
}

ノート

objc_msgSendコメントで Greg Parker が提案したように、明示的なキャストを追加しました。

于 2013-09-08T22:38:27.397 に答える