Reputation: 2332
I'm trying to call a c program from Python using ctypes
. I've got a minimum (non-)working example below.
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);
}
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.
Upvotes: 3
Views: 580
Reputation: 8496
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.
Upvotes: 3