使用Cygwin编译的C程序在Python中调用时卡住了

3
我想使用ctypes从Python调用一个C程序。下面是一个最小的(非)工作示例。

C程序

这是我要调用的C程序,只是标准的hello world程序。我在Windows上使用eclipse和cygwin gcc编译器编译它,生成一个.dll文件。

main.h

#ifndef INC_MAIN_H_
#define INC_MAIN_H_

void helloWorld();

unsigned char buf[] = "Hello World!";

#endif /* INC_MAIN_H_ */

main.c

#include <stdio.h>
#include "main.h"

void helloWorld(){
    printf("\n%s\n\n", buf);
}

Python程序

然后我编写了一个Python脚本来加载我的.dll文件并调用helloWorld函数。重要的是,我同时复制了我创建的.dll文件和cygwin1.dll文件。

helloWorld.py

from ctypes import CDLL
import os

def loadDLL(file):
    file = file.replace('\\','/')
    if not os.path.exists(file):
        raise FileNotFoundError(file)

    print('Opening DLL File:', file)
    dll = CDLL(file)

    return dll

if __name__ == '__main__':
    dll = loadDLL(FILE_TO_LOAD)
    dll.helloWorld()

当我运行这个程序时,loadDLL正常工作并加载DLL。然而,从c程序调用helloWorld函数会导致程序挂起。
奇怪的是,如果我用无害的东西(例如int x = 0)替换printf行,它就可以执行,但会打印出一个看似随机的数字。
有人能指出我做错了什么吗?或者甚至有一种方法来找出问题出在哪里?
顺便说一句,我能够在Linux系统上获得几乎相同的设置,并且正常工作,所以我猜这是由于我设置的Windows环境引起的,但我无法猜测真正的原因。
更新:
我不是写这篇答案,因为它没有解决问题的本质,只是灵魂。

Jean-Francois Fabre的建议下,我放弃了cygwin,改用mingw,现在一切都按照预期运行了。显然cygwin的工作方式很奇怪。Ahmed Masud找到了一个有用的链接,介绍了如果编译cygwin程序以供外部库使用,但这似乎比仅仅使用mingw带来的麻烦还要多(更不用说我在试图使用cygwin时遇到的其他问题了)。

顺便提一下,为了看到c程序的输出,这个程序也必须在命令行上运行。在python的IDLE中运行无法捕获c程序的printf输出。


如果可以的话,我个人会放弃Cygwin而选择MinGW... - Jean-François Fabre
嗯,嘿,他可能是对的 :P - Ahmed Masud
1
啊,找到了一些东西.... https://cygwin.com/cygwin-ug-net/dll.html 显然,Cygwin在处理DLL方面有些奇怪。MinGW DLL作为标准的Windows DLL工作,而它们需要调整(请阅读页面底部)才能与Cygwin一起使用。 - Ahmed Masud
你的 C 程序可能没有返回任何内容吗? - 0x11
1
问题在于你正在从非cygwin的Python中调用cygwin程序,并且期望不正确。cygwin程序具有与普通Windows程序不同的范例。 - matzeri
显示剩余8条评论
1个回答

3
问题在于你正在从非cygwin的Python中调用cygwin程序,并且期望不正确。
cygwin程序具有与普通Windows程序不同的范式(类似于Posix)。
建议使用cygwin Python和编译器进行测试,或者使用两个Windows版本。

对于未来的用户,我确实使用了个人安装的Python并不是Cygwin安装的Python。一旦我切换了,它就像预期的那样工作了。 - zephyr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接