Swift项目中的C代码

Swift项目中的C代码,c,swift,bridging-header,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

我有一个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;
}

这在本文中有广泛的介绍。Objective-C是C的超集,因此Objective-C的所有指令对C同样有效

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

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

是的

这在本文中有广泛的介绍。Objective-C是C的超集,因此Objective-C的所有指令对C同样有效

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


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

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

正如Rob Napier所指出的,一个显而易见的选择就是将C代码编译成一个可执行文件,并使用类似于popen(3)的东西来读写它的标准IO设备,就像读写任何其他的
文件*
一样

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

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

另外一种不必更改所有
printf
s的方法是使用
funopen(3)
或friends,尤其是
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");
}
#包括
int passToSwift(void*cookie,const char*buffer,int len)
{
(无效)曲奇;
//用你收到的缓冲区做些事情
回程透镜;
}
内部主(空)
{
fflush(stdout);
stdout=fwopen(NULL,passToSwift);
printf(“嘿\n”);
}

stdout
的赋值是不可移植的,但在OS X上对我有效。我不知道有任何其他方法可以实现它。(
dup2
funopen
d流提供
EBADF
freopen
需要文件系统中的一个条目)。

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

正如Rob Napier所指出的,一个显而易见的选择就是将C代码编译成一个可执行文件,并使用类似于popen(3)
的东西来读写它的标准IO设备,就像读写任何其他的
文件*
一样

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

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

另外一种不必更改所有
printf
s的方法是使用
funopen(3)
或friends,尤其是
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");
}
#包括
int passToSwift(void*cookie,const char*buffer,int len)
{
(无效)曲奇;
//用你收到的缓冲区做些事情
回程透镜;
}
内部主(空)
{
fflush(stdout);
stdout=fwopen(NULL,passToSwift);
printf(“嘿\n”);
}

stdout
的赋值是不可移植的,但在OS X上对我有效。我不知道有任何其他方法可以实现它。(
dup2
funopen
d流提供
EBADF
freopen
需要文件系统中的一个条目)。

我正在处理一个非常类似的问题。 我有一个关于codereview的可供讨论的解决方案:
也许你也可以把它(或它的一部分)用于你的文字游戏…

我正在处理一个非常类似的问题。 我有一个关于codereview的可供讨论的解决方案: 也许你也可以将其(或其中的一部分)用于文本游戏…

的改进版现在作为Xcode 7项目(和)在github上可用

特别是查看
#define
预处理器语句,以利用到swift的桥接(类似于的答案)