Swift项目中的C代码
我有一个C程序,我想从swift打印它的输出,当它扫描时,我可以通过swift给它输入。这可能吗?我用一个简单的函数尝试了这个方法,它成功了,但是如何用许多调用其他函数的不同函数来实现呢 我知道这个问题有点模糊,但有人能给我指出正确的方向吗 代码示例: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
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的桥接(类似于的答案)