Swift 项目中的 C 代码

C code in Swift Project

我有一个 C 程序,我想从 swift 打印它的输出,当它扫描时我可以通过 Swift 给它输入。这样的事情可能吗?我用一个简单的函数尝试了这个,它成功了,但是有人怎么能用许多不同的函数来调用其他函数呢?

我知道这个问题有点含糊,但有人能指出我正确的方向吗?

代码示例:

int main(int argc, char **argv) {
    int i;
    int hitme;
    char ch;
    prelim();

    if (argc > 1) { // look for -f option
        if (strcmp(argv[1], "-f")== 0) {
            coordfixed = 1;
            argc--;
            argv++;
        }
    }


    if (argc > 1) {
        fromcommandline = 1;
        line[0] = '[=11=]';
        while (--argc > 0) {
            strcat(line, *(++argv));
            strcat(line, " ");
        }
    }
    else fromcommandline = 0;


    while (TRUE) { /* Play a game */
        setup();
        if (alldone) {
            score(0);
            alldone = 0;
        }
        else makemoves();
        skip(2);
        stars();
        skip(1);

        if (tourn && alldone) {
            printf("Do you want your score recorded?");
            if (ja()) {
                chew2();
                freeze(FALSE);
            }
        }
        printf("Do you want to play again?");
        if (!ja()) break;
    }
    skip(1);
    prout("May the Great Bird of the Galaxy roost upon your home planet.");
    return 0;
}

是的。

Using Swift with Cocoa and Objective-C 对此进行了广泛介绍。 Objective-C 是 C 的超集,因此 Objective-C 的所有指令对 C 都同样适用。

简短的版本是您只需将 C 代码添加到您的项目中,将其 header 导入您的 Objective-C 桥接 Header,然后 C 函数将在Swift(使用各种自动翻译)。

就是说,如果您真的想读取输出(即这些 printf 调用的结果),那就有点不同了。如果可以的话,我会避免它。否则你需要做一些事情,比如将 C 程序构建为它自己的可执行文件,并在 Swift 中使用 NSTask 来调用它并捕获输出,或者你必须用类似 fdopen。完全正确地做到这一点很痛苦。

我将重点关注您问题的第二部分,即如何与使用标准 IO 工具的 C 代码进行交互:

Rob Napier 指出的显而易见的选择就是将 C 代码编译成可执行文件并使用类似于 popen(3) 的东西来读取和写入其标准 IO 设施,就像您 [=43] =] 任何其他 FILE*.

另一种方法是找出使用 stdio 的地方并更改这些函数。例如你可以使用

#ifdef STANDALONE
#define print printf
#else
#define print passToSwift
#endif

然后您可以将所有 printfs 更改为 prints 并且只是 #define 您希望 C 代码运行的模式。如果 STANDALONE 是如果未定义,您将必须提供一个 passToSwift 函数来连接您的 C 和 Swift 功能。

无需更改所有 printf 的另一种方法是使用 funopen(3) 或朋友,尤其是 fwopen(3)。使用 fwopen(3) (man fwopen) 你可以提供一个 passToSwift 函数,只要有东西被写入 stdout.

就会被调用
#include <stdio.h>
int passToSwift(void * cookie, const char * buffer, int len)
{
    (void)cookie;
    // do stuff with the buffer you recieved
    return len;
}

int main(void)
{
    fflush(stdout);
    stdout = fwopen(NULL, passToSwift);
    printf("Hey\n");
}

stdout 的分配不可移植,但在 OS X 上对我有效。我不知道有任何其他方法可以实现它。 (dup2funopend 流提供 EBADFfreopen 期望在文件系统中有一个条目)。

我正在解决一个非常相似的问题。 我有一个解决方案可供讨论代码审查:C hack: replace printf to collect output and return complete string by using a line buffer 也许您也可以将它(或其中的一部分)用于您的文字游戏...

改进版C hack: replace printf to collect output and return complete string by using a line buffer is now availabe on github as Xcode 7 project swift-C-string-passing (and standalone gcc version).

特别查看 #define 预处理器语句以利用 swift 的桥梁(类似于 a3f 的回答)。

我的解决方案能够将字符串传入和传出到 C 代码。但是如何从用户那里检索到答案呢? IE。 ja() 函数有什么作用?