Search code examples
pythoncdllcygwin

C Program Compiled with Cygwin and Called from Python Hangs


I'm trying to call a c program from Python using ctypes. I've got a minimum (non-)working example below.

C Program

Here is the C program I'm trying to call into. Just your standard hello world program. I compile this, on windows, using eclipse and the cygwin gcc compiler to produce a .dll file.

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 Program

Then I write a python script to load my .dll and call the helloWorld function. Importantly, I do pull over both the .dll I created and the 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()

When I go to run this program, loadDLL works just fine and loads the DLL. However, calling the helloWorld function from the c program causes it to hang.

Oddly enough, if I replace the printf line with something innocuous (e.g., int x = 0), it executes fine but prints out a seemingly random number.

Can anyone point me to what I'm doing wrong? Or even a way to figure out what's going wrong?

Btw, I was able to get a nearly identical setup to work just fine on a linux system, so I'm guessing it's due to the windows environment that I've setup, but I couldn't begin to guess what it really is.

UPDATE

I'm not writing this as an answer because it doesn't solve the letter of the problem, but only the spirit.

At Jean-Francois Fabre's suggestion I dropped cygwin for mingw and things now work as expected. Apparently cygwin works in strange ways. Ahmed Masud was able to find a useful link about how cygwin programs should be compiled if they're to be used for external libraries, but that seemed like much more trouble that just using mingw (not to mention the other problems I'd already encountered trying to use cygwin for this).

FWIW, this program must also be run in on the command line in order to see the output of the c program. Running in python's IDLE did not capture the printf output from the c program.


Solution

  • The problem is that you are calling a cywgin program from a NOT cygwin python and having the wrong expectation.

    cygwin programs have different paradigma (Posix-like) than normal windows programs.

    It is recommended to test with both cygwin python and compiler, or both windows one.