Python 3 输出重定向使用C/C++
By:gddsky
目标
希望将Python 3的输出重定向到自定义的输出目标。
核心
Python使用sys.stdout、sys.stderr做输出目标,只要我们替换这两个值就可以重定向到我们自定义目标。替换的值的规则在Python的文档中sys (module)的sys.stdout上面说明只要添加一个write函数就可以了。像这样:
write(self, str)
我们只要在这个函数里面调用我们自己的输出函数就可以实现该目标了。
方案
在C++中写一个Python模块,并导入
在C++中利用PyRun_SimpleString建立一个PyObject去替换原始的sys.stdout、sys.stderr
搞定!!!
代码
模块定义部分代码(用python demo下的例子改写的)
static PyObject *console_write(PyObject *self, PyObject* args)
{
if (s_pyConsoleNotify != NULL)
{
const char* pMsgString=0;
if (!PyArg_ParseTuple( args, "s", &pMsgString ))
{
&n ......
Python 3 输出重定向使用C/C++
By:gddsky
目标
希望将Python 3的输出重定向到自定义的输出目标。
核心
Python使用sys.stdout、sys.stderr做输出目标,只要我们替换这两个值就可以重定向到我们自定义目标。替换的值的规则在Python的文档中sys (module)的sys.stdout上面说明只要添加一个write函数就可以了。像这样:
write(self, str)
我们只要在这个函数里面调用我们自己的输出函数就可以实现该目标了。
方案
在C++中写一个Python模块,并导入
在C++中利用PyRun_SimpleString建立一个PyObject去替换原始的sys.stdout、sys.stderr
搞定!!!
代码
模块定义部分代码(用python demo下的例子改写的)
static PyObject *console_write(PyObject *self, PyObject* args)
{
if (s_pyConsoleNotify != NULL)
{
const char* pMsgString=0;
if (!PyArg_ParseTuple( args, "s", &pMsgString ))
{
&n ......
Python 3 输出重定向使用C/C++
By:gddsky
目标
希望将Python 3的输出重定向到自定义的输出目标。
核心
Python使用sys.stdout、sys.stderr做输出目标,只要我们替换这两个值就可以重定向到我们自定义目标。替换的值的规则在Python的文档中sys (module)的sys.stdout上面说明只要添加一个write函数就可以了。像这样:
write(self, str)
我们只要在这个函数里面调用我们自己的输出函数就可以实现该目标了。
方案
在C++中写一个Python模块,并导入
在C++中利用PyRun_SimpleString建立一个PyObject去替换原始的sys.stdout、sys.stderr
搞定!!!
代码
模块定义部分代码(用python demo下的例子改写的)
static PyObject *console_write(PyObject *self, PyObject* args)
{
if (s_pyConsoleNotify != NULL)
{
const char* pMsgString=0;
if (!PyArg_ParseTuple( args, "s", &pMsgString ))
{
&n ......
一、概述及示例代码
Delphi中包括许多已经封装好的类及控件,其中的非可视化控件库以功能方式划分可处理诸多应用需求。若使用C++实现系统时对某些功能简单调用delphi中现成的库时即可。因此将delphi中的库以DLL形式封装好之后如何将方法导出可供C++调用是本文记录的重点。C++调用的方式有多种,在这里只讨论一种静态编译方式,一是为了代码的规范可读性,二是防止接口变化带来的维护问题。
Delphi对外接口单元:
library ftpUpload;
uses
SysUtils,
Classes,
dialogs,
FileUpLuo in
'FileUpLuo.pas';
var
mTask :
TFtpUpFileLuo;
taskParam :
SUpTask;
{$R *.res}
function SendFile_luo(szSrcFile: pchar; szDesFile:
pchar;
szFtpServer: pchar; strUsername: pchar;
strPassword: pchar): Integer;
export; stdca ......
一、概述及示例代码
Delphi中包括许多已经封装好的类及控件,其中的非可视化控件库以功能方式划分可处理诸多应用需求。若使用C++实现系统时对某些功能简单调用delphi中现成的库时即可。因此将delphi中的库以DLL形式封装好之后如何将方法导出可供C++调用是本文记录的重点。C++调用的方式有多种,在这里只讨论一种静态编译方式,一是为了代码的规范可读性,二是防止接口变化带来的维护问题。
Delphi对外接口单元:
library ftpUpload;
uses
SysUtils,
Classes,
dialogs,
FileUpLuo in
'FileUpLuo.pas';
var
mTask :
TFtpUpFileLuo;
taskParam :
SUpTask;
{$R *.res}
function SendFile_luo(szSrcFile: pchar; szDesFile:
pchar;
szFtpServer: pchar; strUsername: pchar;
strPassword: pchar): Integer;
export; stdca ......
指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。 要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的 类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区。让我们分别说明。
先声明几个指针放着做例子:
例一:
(1)int*ptr;
(2)char*ptr;
(3)int**ptr;
(4)int(*ptr)[3];
(5)int*(*ptr)[4];
指针的类型
从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。这是指针本身所具有的类型。让我们看看例一中各个指针的类型:
(1)int*ptr;//指针的类型是int*
(2)char*ptr;//指针的类型是char*
(3)int**ptr;//指针的类型是int**
(4)int(*ptr)[3];//指针的类型是int(*)[3]
(5)int*(*ptr)[4];//指针的类型是int*(*)[4]
怎么样?找出指针的类型的方法是不是很简单? ......
from:邹鑫的专栏
什么时候需要创建线程池呢?简单的说,如果一个应用需要频繁的创建和销毁线程,而任务执行的时间又非常短,这样线程创建和销毁的带来的开销就不容忽视,这时也是线程池该出场的机会了。如果线程创建和销毁时间相比任务执行时间可以忽略不计,则没有必要使用线程池了。
下面是Linux系统下用C语言创建的一个线程池。线程池会维护一个任务链表(每个CThread_worker结构就是一个任务)。
pool_init()函数预先创建好max_thread_num个线程,每个线程执thread_routine ()函数。该函数中
while (pool->cur_queue_size == 0)
{
pthread_cond_wait (&(pool->queue_ready),&(pool->queue_lock));
}
表示如果任务链表中没有任务,则该线程出于阻塞等待状态。否则从队列中取出任务并执行。
pool_add_worker()函数向线程池的任务链表中加入一个任务,加入后通过调用pthread_cond_signal (&(pool->queue_ready))唤醒一个出于阻塞状态的线程(如果有的话)。
pool ......
from:邹鑫的专栏
什么时候需要创建线程池呢?简单的说,如果一个应用需要频繁的创建和销毁线程,而任务执行的时间又非常短,这样线程创建和销毁的带来的开销就不容忽视,这时也是线程池该出场的机会了。如果线程创建和销毁时间相比任务执行时间可以忽略不计,则没有必要使用线程池了。
下面是Linux系统下用C语言创建的一个线程池。线程池会维护一个任务链表(每个CThread_worker结构就是一个任务)。
pool_init()函数预先创建好max_thread_num个线程,每个线程执thread_routine ()函数。该函数中
while (pool->cur_queue_size == 0)
{
pthread_cond_wait (&(pool->queue_ready),&(pool->queue_lock));
}
表示如果任务链表中没有任务,则该线程出于阻塞等待状态。否则从队列中取出任务并执行。
pool_add_worker()函数向线程池的任务链表中加入一个任务,加入后通过调用pthread_cond_signal (&(pool->queue_ready))唤醒一个出于阻塞状态的线程(如果有的话)。
pool ......
1、开发环境请参考《搭建ACE-5.7.4+VS2008开发环境》一文
2、gSOAP库,下载地址:http://gsoap2.sourceforge.net/,本文使用的版本是:gsoap_2.7.15,gSOAP的编程可以参考doc目录下的soapdoc2.pdf,官方文档写的非常详细。
让我们开始gSOAP编码旅程:
1、创建gsoap_server.h:
//gsoap ns2 service namespace: http://localhost:9908/ccm_mimport/services.wsdl
//gsoap ns2 service location: http://localhost:9908/ccm_mimport/services
typedef char * xsd__string; // encode char * value as the xsd:string schema type
typedef int xsd__int; // encode xsd__int value as the xsd:int schema typ
struct ns2__makeCardNotifyReqBean
{
xsd__string id_makecard_order;
xsd__int card_type;
xsd__string file_name;
xsd__string start_card_serial;
xsd__string end_card_serial;
xsd__int card_count;
};
struct ns2__makeCardNotifyRspBean
{
xsd__int result; //结果
xsd__string error_desc; //错误描述
};
//卡数据生成结果通知接口
int ns2__makeCardNotify(struct ns2__makeCardNotifyReqBean req, struct ns2__makeCardNotif ......
1、开发环境请参考《搭建ACE-5.7.4+VS2008开发环境》一文
2、gSOAP库,下载地址:http://gsoap2.sourceforge.net/,本文使用的版本是:gsoap_2.7.15,gSOAP的编程可以参考doc目录下的soapdoc2.pdf,官方文档写的非常详细。
让我们开始gSOAP编码旅程:
1、创建gsoap_server.h:
//gsoap ns2 service namespace: http://localhost:9908/ccm_mimport/services.wsdl
//gsoap ns2 service location: http://localhost:9908/ccm_mimport/services
typedef char * xsd__string; // encode char * value as the xsd:string schema type
typedef int xsd__int; // encode xsd__int value as the xsd:int schema typ
struct ns2__makeCardNotifyReqBean
{
xsd__string id_makecard_order;
xsd__int card_type;
xsd__string file_name;
xsd__string start_card_serial;
xsd__string end_card_serial;
xsd__int card_count;
};
struct ns2__makeCardNotifyRspBean
{
xsd__int result; //结果
xsd__string error_desc; //错误描述
};
//卡数据生成结果通知接口
int ns2__makeCardNotify(struct ns2__makeCardNotifyReqBean req, struct ns2__makeCardNotif ......
#include <stdio.h>
#define MAXHIST 15
#define MAXWORD 11
#define IN 1
#define OUT 0
//打印输入中单词长度的水平方向直方图,
void main()
{
int c, i, nc, state;
int len; //length of each bar
int maxvalue; //maximum value for wl[]
int ovflow; //number of overflow words
int wl[MAXWORD]; //word length count
state = OUT;
nc = 0; //number of chars in a word
ovflow = 0;
for (i = 0; i < MAXWORD; ++i)//数组初始化
wl[i] = 0;
while((c = getchar()) != EOF){
if (c == ' ' || c == '\n' || c == '\t'){
state = OUT;
if(nc > 0)
if(nc < MAXWORD)
......