标签 C语言 下的文章

用Base64编码UTF-8字符串(C语言)

//将ansi字符串转为UTF-8之后转为Base64编码供邮件使用
#include <stdio.h>
#include <windows.h>
#include <string>
#include "base64.h"
using namespace std;

int main()
{
string test1="輸入模式";
WCHAR test1_w[255]={0};
char test1_u8[255]={0};
//mb->wc
int len=MultiByteToWideChar(CP_ACP,0,test1.c_str(),-1,NULL,0);
MultiByteToWideChar(CP_ACP,0,test1.c_str(),-1,test1_w,len);
//wc->utf8
DWORD dwNum = WideCharToMultiByte(CP_UTF8,NULL,test1_w,-1,NULL,0,NULL,FALSE);
WideCharToMultiByte (CP_UTF8,NULL,test1_w, -1, test1_u8, dwNum,NULL,FALSE);
//encode
string test2 = base64_encode((const unsigned char *)test1_u8, strlen(test1_u8)+1);
}

有一个字符串需要以UTF-8字符集编码转换为Base64编码。解释一下以上代码。 test1是一个ansi字符串,通过 MultiByteToWideChar 函数将 test1 ansi字符串转换为 test1_w UTF-16 LE宽字符。然后又通过WideCharToMultiByte 将宽字符串转为UTF-8字符串 test1_u8。 然后通过base64_encode函数转为Base64编码。base64_encode函数来自 René Nyffeneggerhttp://www.adp-gmbh.ch/cpp/common/base64.html

"輸入模式"这四个繁体字的ANSI 16进制编码(中文系统也就是GBK编码)是

DD94 C8EB C4A3 CABD

转换成UTF-8的16进制编码是:

E8BCB8 E585A5 E6A8A1 E5BC8F

上文函数两次调用WideCharToMultiByte和两次调用MultiByteToWideChar 的第一次调用返回值是获取转换后编码buffer的字节数。len等于5,需要4个WCHAR+1个'\0'。 dwNum等于13,需要12 Bytes+1个'\0'。

Windows 8.1 GetVersionEx返回6.2.9200 Bug?

某程序需要判断当前Windows系统的版本号。Windows系统的版本号格式为:majorVersion.minorVersion.BuildNumber.

Windows 8 RTM的版本号的6.2.9200 Windows 8.1 Preview的版本好是6.3.9431

使用以下代码在Win8下面运行正常的显示为6.2.9200 , 但是接下来在Win8.1下面测试尽然还是6.2.9200。而通过Win8.1自带的命令行systeminfo(采用WMI方式)返回的是正确的版本号。

OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(osvi);
GetVersionEx(&osvi);
sprintf(szBuf,"OS Version %d.%d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber);
MessageBox(hWnd, szBuf, szBuf, MB_OK);

google了一下,MSDN论坛上有个帖子遇到同样的问题。实际上这个问题并非bug,而是微软有意为之。如果程序的目标运行平台不需要支持Win8.1,那么GetVersion(Ex)就给你返回6.2,除非通过App manifests方式指定程序支持Win8.1系统:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<assemblyIdentity
type="win32"
name=SXS_ASSEMBLY_NAME
version=SXS_ASSEMBLY_VERSION
processorArchitecture=SXS_PROCESSOR_ARCHITECTURE
/>
<description> my app exe </description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"
/>
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<app>
* <!-- Windows 8.1 -->
* <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
</app>
</compatibility>
</assembly>

在Win8.1系统以后GetVersion(Ex)被放到兼容层(shim)里面,这样GetVersion(Ex)并不一定会返回系统真实的版本号。取而代之可以采用VersionHelpers方式获取真实的系统版本号。

C++
#include <VersionHelpers.h>

if (!IsWindows8OrGreater())
{
MessageBox(NULL, "You need at least Windows 8", "Version Not Supported", MB_OK);
}

关于此话题可以参看Windows and Windows Server compatibility cookbook: Windows 8Windows 8.1 Preview, and Windows Server 2012 R2 Preview关于versioning章节。

wrong logic in yajl_tree_get (returns NULL even when val exists)

用yajl不要用主页(lloyd.github.com/yajl/)的2.0.1,已经很久没有更新了,有个致命bug,如标题所说。

ISSUE:https://github.com/lloyd/yajl/issues/52

SO上的讨论:http://stackoverflow.com/questions/7309992/parsing-json-with-yajl-in-c

简而言之,第一个key存在,但是值返回NULL。

此commit已经fix 9c2948a33165c650122d131f31140c15321908f5

请用git clone git://github.com/lloyd/yajl.git 保持更新。

"_wWinMainCRTStartup" is not __stdcall with 12 bytes of arguments

vc6链接报错:

../out/WIMMgr.dll : warning LNK4086: entrypoint "_wWinMainCRTStartup" is not __stdcall with 12 bytes of arguments; image may not run

原来编译unicode版dll的时候,无需将entry point设置为_wWinMainCRTStartup。解决方法:去掉_wWinMainCRTStartup即可

问题:winform程序启动后自动最小化

问题:winform程序启动后自动最小化

本来默认情况下winform程序调试,运行,双击exe直接显示界面了。但是今天碰到了双击exe之后界面直接最小化到任务栏的问题。

我排查的思路是:首先程序有多个Form,Program.cs里面new的是Form1打开就最小化。我尝试把Form1替换为其他的Form(比如Form2....),结果是:Form2最小化,Form3,Form4等正常,所有问题肯定在Form2里面

这里说一下为什么,Program.cs里面new的是Form1也成了最小化,因为这个程序Form1是其他所有Form的Parent Form。

接下来,看Form2的构造函数里面的内容,依次注释InitializeComponent等一些影响程序界面元素的函数。结果没发现问题。。

接下来来到了UpdateDeviceList()函数,在注释一下语句后,程序正常显示:

DriveDetector dd = new DriveDetector();
dd.DeviceArrived += new DriveDetectorEventHandler(OnDriveArrived);
dd.DeviceRemoved += new DriveDetectorEventHandler(OnDriveRemoved);

DriveDetector是别人写的检查pnp设备插入,原理是重载WndProc,所以必须要有一个Form,所以DriverDetector的构造函数在没有指定窗口的情况下自动简历一个隐藏窗口:this.Visible = false;,导致程序启动后最小化,通过指定窗口为this后,问题解决。

DriveDetector dd = new DriveDetector(this);