Swift Project中的C代码

时间:2015-12-12 14:35:26

标签: c swift bridging-header

我有一个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] = '\0';
        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;
}

4 个答案:

答案 0 :(得分:1)

Using Swift with Cocoa and Objective-C广泛涵盖了这一点。 Objective-C是C的超集,因此Objective-C的所有指令同样适用于C。

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

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

答案 1 :(得分:1)

我将重点讨论问题的第二部分,如何与使用标准IO设施的C代码进行交互:

Rob Napier指出的显而易见的选择只是将C代码编译成可执行文件并使用类似于$('.univ').hover(function() { if ($(this).find('.sub-content').length>0) { $(this).addClass('active'); } }); $('.heading').hover(function() { var parent = $(this).parent(); if( parent.hasClass('sub-content')) parent.addClass('active'); }); 的东西来读取和写入其标准IO工具,就像读取/写入任何其他内容一样popen(3)

另一种方法是寻找使用stdio的地方并改变这些功能。例如,您可以使用

FILE*

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

无需更改所有passToSwift的另一种方法是使用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"); } 的分配不可移植,但在OS X上对我有用。我不知道有任何其他方法可以实现它。 (stdoutdup2 d流提供EBADFfunopen期望文件系统中有一个条目。

答案 2 :(得分:1)

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

答案 3 :(得分:1)

C hack: replace printf to collect output and return complete string by using a line buffer的改进版现在github上可用作Xcode 7项目swift-C-string-passing(以及standalone gcc version)。

特别要查看#define预处理程序语句,以便将桥接器用于swift(类似于a3f的答案)。

我的解决方案能够将字符串输入和输出到C代码。但是如何从用户检索答案?即ja()函数做了什么?