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
然后您可以将所有 printf
s 更改为 print
s 并且只是 #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 上对我有效。我不知道有任何其他方法可以实现它。 (dup2
为 funopen
d 流提供 EBADF
,freopen
期望在文件系统中有一个条目)。
我正在解决一个非常相似的问题。
我有一个解决方案可供讨论代码审查: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()
函数有什么作用?
我有一个 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
然后您可以将所有 printf
s 更改为 print
s 并且只是 #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 上对我有效。我不知道有任何其他方法可以实现它。 (dup2
为 funopen
d 流提供 EBADF
,freopen
期望在文件系统中有一个条目)。
我正在解决一个非常相似的问题。 我有一个解决方案可供讨论代码审查: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()
函数有什么作用?