POSIX on Windows (2) Cygwin

| | 评论(0)

Get blocked on Interix, I turned to Cygwin.


Cygwin platform supports POSIX and unix style sockets APIs, so there is no big effort to get project build. Make sure you installed Cygwin with all "Devel" features selected.

1. Python on Cygwin

Cygwin has a embedded Python and supports calling functions in DLLs with ctypes interface. There are other options to call DLL in Cygwin, while ctypes is the most popular. Make sure install the updated ctypes on cygwin.

1.1 Python call C

Although the "-shared" options generates a DLL in binary, the python in Cygwin ask for names libxxx.so. Make sure the makefile generates library with suffix .so.

1.2 C call Python, Garbage Collection

If we pass a reference of a Python function to C, Cygwin may hang while C call the python function back. The problem is, python may consider the python function is of no use and release the memory. The Python doc talk about this issue and gives a solution to use the Py_XINCREF() and Py_XDECREF() to increase anddecrease the reference number to the python function. This is a kind of too complex, and our C program does not know if the caller is a Python. A better solution is to define a global variable in Python to hold the reference to the python function:

global ref_func = (TO_C_FUNC)pyFunc

and python will not release the memory.

2. Java JNA on Cygwin

Make sure you have the updated jna.jar (JNA, Java Native Access) package before you can proceed. Cygwin does not have a platform specific java, people simply use java for windows. Goto Oracle/Sun website to download and installed jre(java run-time environment) AND jdk (java development kit). Java on Windows recognize *.dll files only, please copy libxyz.so tp xyz.dll and place the DLL file in the same folder of your *.class (the compiled java) file.Since cygwin’s lib*.so is actually dll format, what we need to do is to add a stdcall option g++ -Wl,--add-stdcall-alias -shared -o myDll.dll myNativeCode1.c myNativeCode2.c

JNA(Java native access) enables Java access local C libraries.

However, Java application will hang on calling DLL compiled in Cygwin environment, even with the simplest “hello world” example provided by SUN. A solution mentioned on Cygwin newsgroup is to use minGW compiler with a –mno-cygwin option to generate DLL. Additional option is to generate DLL with MS VC compiler. Both the options make the DLL independent to cygwin1.dll, and that works for the “hello world” example. However, it does not work for us since we rely on cygwin POSIX services.

The problem here is Cygwin library needs a special initialization to setup a 32k(Cygwin doc talks about 4k but 32k is more accurate in current version Cygwin_NT5.1) TLS area at the bottom of the stack for signal emulation(). While we call LoadLibrary from a non-cygwin application (e.g java), the crt start objects in Cygwin was skipped and the TLS area was not reserved.

Cygwin’s doc mentioned a method to build crt0.c to a static lib, then combine it to a Visual C++ application. The cygwin_dll_init() is invoked in crt.c. Unfortunately this way is proved to have problem in spawn new threads.

An applicable method was mentioned here, which is to compile a cygwin local launcher to do the setup and create Java VM. Sun has give an example to invoke Java VM from C, and I write one based on the example. 不过做好以后我杯具地发现在Java的根目录下就有一个src.zip,其中有Launcher源代码。。。好在我的还满好用。

Now try “ldd java_launcher.exe” to make sure the launcher is linked to cygwin1.dll.

Note: while calling the java VM, the classpath must be in Windows format, such as "D:\\\\codes\\\\proj\\\\java". It can be got by execute "cygpath". A example $./java_launcher -classpath `cygpath -w -a ./` myjavatest

3. POSIX local domain sockets (or local connections)

I use connections both in IP sockets or in local sockets. The local sockets links to a file name, eg /tmp/my_connectioons/x1. The path and file are not necessary exists on Linux platform, however, the cygwin implementation asks for path "/tmp/my_connectioons/xyz/" physically exists. I add a function mkdirs() to detect and build the path.

Cygwin will return error with code EINPROGRESS for a non-blocking link while calling connect(). This should be considered as success. Linux simply return success in this case.

4. Perl

Some perl function behavior is kind of difference on Cygwin. eg

$string = `cat filename`

might not get the ouput strings for Perl for Cygwin. I do not know how to solve it yet.




此日记由mach发表于August 24, 2010 9:16 AM

此Blog上的上一篇日记POSIX on Windows (1) Interix



Powered by Movable Type 4.23-en