MFC Python混合编程(以发送邮件为例)

1. Python代码

import smtplib
from email.header import Header
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication

def sendEmail(mail_host, mail_user, mail_pass, sender, content, title, receivers):    
    message = MIMEText(content, 'plain', 'utf-8')  # 内容, 格式, 编码
    message['From'] = "{}".format(sender)
    message['To'] = ",".join(receivers)
    message['Subject'] = title

    try:
        smtpObj = smtplib.SMTP_SSL(mail_host, 465)  # 启用SSL发信, 端口一般是465
        smtpObj.login(mail_user, mail_pass)  # 登录验证
        smtpObj.sendmail(sender, receivers, message.as_string())  # 发送
        return True
    except smtplib.SMTPException as e:
        return False
        
def sendAppendix(mail_host, mail_user, mail_pass, sender, content, title, receivers, path, filename):
    msg=MIMEMultipart()
    msg['From']="{}".format(sender)
    msg['To']=','.join(mail_user)
    msg['Subject']=title
    text=MIMEText(content, 'plain', 'utf-8')
    msg.attach(text)
    
    flag = is_chinese(filename)
    if flag:
        with open(path,'rb') as f:
            att=MIMEApplication(f.read())
            att.add_header('Content-Disposition','attachment',filename=('gb2312','',filename))
            msg.attach(att)
    else:
        with open(path,'rb') as f:
            att=MIMEApplication(f.read())
            att.add_header('Content-Disposition','attachment',filename=filename)
            msg.attach(att)
    try:
        server=smtplib.SMTP_SSL(mail_host,465)
        server.login(mail_user,mail_pass)
        server.sendmail(sender,receivers,str(msg))
        return True
    except smtplib.SMTPException as e:
        return False
    
def is_chinese(string):
    for ch in string:
        if u'\u4e00' <= ch <= u'\u9fff':
            return True

    return False

 

mail_host, mail_user, mail_pass这些信息是邮件服务器的,为了不让别人看到,我写在MFC代码里面,然后通过传参的方式传给python函数。至于怎么在VS里配置python,这里不说,百度都有,也很好配置,唯一需要注意的地方可能是lib文件的时候有蹊跷,这个网上也都有,不赘述。

 

2. MFC 代码

void CSendEmailDlg::OnBnClickedBtnTest() //按钮响应函数
{
    // TODO: 在此添加控件通知处理程序代码
    char *mail_host = "smtp.163.com";
    char *mail_user = "xxx";
    char *mail_pass = "yyyyyyyyy";//这是163的授权码,至于怎么获得,搜索就好了
    char *sender = "xxx<xxx@163.com>";
    char *title = "这是一封 测试邮件";//要发送中文要注意转换的,不然PyEval_CallObject这个函数会调用失败
    char *content = "测试邮件";
    

/这里是转换中文,也就是先将ANSI转换为UNICODE,然后再将UNICODE转换为UTF-8,就可以发送中文了
    wchar_t * w_title = AnsiToUnicode(title);
    char *c_title = UnicodeToUtf_8(w_title);

    wchar_t * w_content = AnsiToUnicode(content);
    char *c_content = UnicodeToUtf_8(w_content);

    
    Py_Initialize();//使用python之前,要调用Py_Initialize();这个函数进行初始化
    if (!Py_IsInitialized())
    {
        AfxMessageBox(L"初始化失败!");
        return;
    }
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('./')");//这一步很重要,修改Python路径

    PyObject * pModule = NULL;//声明变量
    PyObject * pFunc = NULL;// 声明变量

    pModule = PyImport_ImportModule("send_email");//这里是要调用的文件名
    if (!pModule)        // 加载模块失败
    {
        AfxMessageBox(L"Load python module fail !");
        Py_Finalize();
        return;
    }
    pFunc = PyObject_GetAttrString(pModule, "sendEmail");//这里是要调用的函数名.
    if (!pFunc || !PyCallable_Check(pFunc))  // 验证是否加载成功
    {
        AfxMessageBox(L"Load python function fail !");
        Py_Finalize();
        return;
    }

///这里是传参数
    PyObject * pyParams = PyTuple_New(7);
    PyTuple_SetItem(pyParams, 0, Py_BuildValue("s", mail_host));
    PyTuple_SetItem(pyParams, 1, Py_BuildValue("s", mail_user));
    PyTuple_SetItem(pyParams, 2, Py_BuildValue("s", mail_pass));
    PyTuple_SetItem(pyParams, 3, Py_BuildValue("s", sender));
    PyTuple_SetItem(pyParams, 4, Py_BuildValue("s", c_content));
    PyTuple_SetItem(pyParams, 5, Py_BuildValue("s", c_title));
    PyTuple_SetItem(pyParams, 6, Py_BuildValue("ss", "xxx@163.com", "xxxx@qq.com"));//这里写你要发邮件给谁.
    PyObject* pRet = PyEval_CallObject(pFunc, pyParams);//调用函数
    if (pRet)  // 验证是否调用成功
    {
        long result = PyLong_AsLong(pRet);
        if (!result)
        {
            AfxMessageBox(L"Send email fail !");
        }
        
    }
    else
    {
        AfxMessageBox(L"Call function fail !");
        Py_Finalize();
        return;
    }
    Py_Finalize();//调用Py_Finalize,这个根Py_Initialize相对应的。
    
}

 

wchar_t* CSendEmailDlg::AnsiToUnicode(const char* szStr)
{
    int nLen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szStr, -1, NULL, 0);
    if (nLen == 0)
    {
        return NULL;
    }
    wchar_t* pResult = new wchar_t[nLen];
    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szStr, -1, pResult, nLen);
    return pResult;
}

char* CSendEmailDlg::UnicodeToUtf_8(const wchar_t* szStr)
{
    int nLen = WideCharToMultiByte(CP_UTF8, 0, szStr, -1, NULL, 0, NULL, NULL);
    if (nLen == 0)
    {
        return NULL;
    }
    char* pResult = new char[nLen];
    WideCharToMultiByte(CP_UTF8, 0, szStr, -1, pResult, nLen, NULL, NULL);
    return pResult;
}

用163邮箱发邮件,需要注意的是,一定要加上163邮箱,也就是你自己的邮箱才可以发送成功,不然,163会将你的邮件作为垃圾邮件,导致发送失败.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kuangbao9

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值