当前位置: 技术问答>linux和unix
怎样写脚踩两条船(cygwin和Win32本地API结合)的程序?
来源: 互联网 发布时间:2016-09-08
本文导语: 要写一个程序,它通过cygwin的fwrite、fread等函数,输入输出,并可以通过mintty等tty显示utf-8,但程序本身是一个Windows程序,即它是通过VC开发的,且要调用Win32的API做其他事情。 怎么弄? | cygl...
要写一个程序,它通过cygwin的fwrite、fread等函数,输入输出,并可以通过mintty等tty显示utf-8,但程序本身是一个Windows程序,即它是通过VC开发的,且要调用Win32的API做其他事情。
怎么弄?
怎么弄?
|
cygload.h:
// cygload.h -*- C++ -*-
//
// Copyright 2005, Red Hat, Inc.
//
// Written by Max Kaehn
//
// This software is a copyrighted work licensed under the terms of the
// Cygwin license. Please consult the file "CYGWIN_LICENSE" for details.
//
// Note that dynamically linking to cygwin1.dll automatically places your code
// under the GPL unless you purchase a Cygwin Contract with Red Hat, Inc.
// See http://www.redhat.com/software/cygwin/ for more information.
// This program has large numbers of progress messages so as to provide
// maximum information about crash locations for anyone without access to
// a Microsoft debugger.
// This file contains the basic infrastructure for connecting an MSVC
// process to Cygwin.
#ifndef __CYGLOAD_H__
#define __CYGLOAD_H__
#include // for GetProcAddress()
#include // for pointer_to_unary_function
#include // for runtime_error
#include
#include
#include
// Convert GetLastError() to a human-readable STL exception.
class windows_error : public std::runtime_error
{
public:
windows_error (const char *message, const char *detail = NULL)
: runtime_error (format (GetLastError (), message, detail)) { }
windows_error(DWORD error, const char *message, const char *detail = NULL)
: runtime_error (format (error, message, detail)) { }
static std::string format (DWORD error, const char *message,
const char *detail);
};
namespace cygwin
{
// Cygwin keeps important thread-local information at the top of the
// stack. Its DllMain-equivalent will do the right thing for any threads
// you spawn, but you need to declare one of these as the very first thing
// in your main() function so horrible things won't happen when cygwin
// overwrites your stack. This will back up the data that will be
// overwritten and restore it when the destructor is called.
class padding {
public:
padding ();
~padding ();
// Verifies that padding has been declared.
static void check ();
private:
std::vector _backup;
char *_stackbase, *_end;
// gdb reports sizeof(_cygtls) == 3964 at the time of this writing.
// This is at the end of the object so it'll be toward the bottom
// of the stack when it gets declared.
char _padding[32768];
static padding *_main;
static DWORD _mainTID;
};
// This hooks your application up to cygwin: it loads cygwin1.dll,
// initializes it properly, grabs some important symbols, and
// spawns a thread to let you receive signals from cygwin.
class connector {
public:
connector (const char *dll = "cygwin1.dll");
~connector ();
// A wrapper around GetProcAddress() for fetching symbols from the
// cygwin DLL. Can throw windows_error.
template void get_symbol (const char *name, T &fn) const;
// Wrappers for errno() and strerror().
int err_no () const;
std::string str_error (int) const;
// Converting between the worlds of Windows and Cygwin.
std::string unix_path (const std::string &windows) const;
std::string win_path (const std::string &unix) const;
private:
HMODULE _library;
int *(*_errno) ();
const char *(*_strerror) (int);
void (*_conv_to_full_posix_path) (const char *, char *);
void (*_conv_to_full_win32_path) (const char *, char *);
public:
// The constructor will automatically hook you up for receiving
// cygwin signals. Just specify a signal and pass in a signal_handler.
typedef std::pointer_to_unary_function signal_handler;
signal_handler *set_handler (int signal, signal_handler *);
private:
// Cygwin signals can only be received in threads that are calling
// interruptible functions or otherwise ready to intercept signals, so
// we spawn a thread that does nothing but call sigwait().
// This is the entry point:
static DWORD WINAPI signal_thread (void *);
// It runs this:
void await_signal ();
// And will execute this on receipt of any signal for which it's
// registered:
void handle_signals (int);
HANDLE _signal_thread;
bool _waiting_for_signals, _signal_thread_done;
CRITICAL_SECTION _thread_mutex;
typedef std::map callback_list;
callback_list _signal_handlers;
};
template void connector::get_symbol (const char *name,
T &symbol) const
{
FARPROC retval = NULL;
retval = GetProcAddress (_library, name);
if (retval == NULL)
throw windows_error ("GetProcAddress", name);
symbol = reinterpret_cast (retval);
}
// cygwin::error converts errno to a human-readable exception.
class error : public std::runtime_error
{
public:
error (connector *c, const char *function, const char *detail = NULL)
: runtime_error (format (c, c->err_no (), function, detail)) { }
error (connector *c, int err_no, const char *function,
const char *detail = NULL)
: runtime_error (format (c, err_no, function, detail)) { }
static std::string format(connector *c, int err_no,
const char *message, const char *detail);
};
}
#endif // __CYGLOAD_H__