存档

‘C++’ 分类的存档

CodeLite命令行中文显示乱码

2016年2月16日 没有评论

有时候想快速写一段C++代码来验证某个功能,感觉使用VS就过于重量级了,关键是衣服自己洗比较洁癖,不喜欢看到有无用的工程项目。所以一直想有一个轻量级的编辑器可以快速编译验证。

于是衣服自己洗发现了CodeLite 和 CodeBlock这2个跨平台,相对轻量的工具。

使用过程中,发现CodeLite的命令行输出中中文显示乱码,一开始还以为自己是软件没有安装好,重新下载安装还是不行。后来经过一番搜索,网上观点认为是 G++ 的问题,需要额外添加编译选项。

选择工程项目,右键属性,切换到Compiler,在 C++ Compile Options 里添加一个选项  -fexec-charset=GBK;  即可。其实还可以把这个配置单独新增进去,以后就只用勾选就可以了。

特别需要说明,设置完成后,需要把项目清理重新编译,不然看不到效果,衣服自己洗在这里被坑了好几次了。

分类: C++, 一句话 标签: ,

win32 程序窗体居中

2015年12月20日 没有评论

C#对于窗体居中很简单,只需要简单设置一个属性就可以了,但是对于C++,还需要额外的写点代码。下面是衣服自己洗分享的代码,可以直接拷贝到项目中。

inline static BOOL CenterWindow(HWND hwndWindow,bool isDesktopParent = true)
{
HWND hwndParent;
RECT rectWindow, rectParent;

hwndParent = isDesktopParent ? GetDesktopWindow() : GetParent(hwndWindow);

//make the window relative to its parent
if (hwndParent != nullptr)
{
GetWindowRect(hwndWindow, &rectWindow);
GetWindowRect(hwndParent, &rectParent);

int nWidth = rectWindow.right – rectWindow.left;
int nHeight = rectWindow.bottom – rectWindow.top;

int nX = ((rectParent.right – rectParent.left) – nWidth) / 2 + rectParent.left;
int nY = ((rectParent.bottom – rectParent.top) – nHeight) / 2 + rectParent.top;

int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);

//make sure the window never moves outside of the screen
if (nX < 0) nX = 0;
if (nY < 0) nY = 0;
if (nX + nWidth > nScreenWidth) nX = nScreenWidth – nWidth;
if (nY + nHeight > nScreenHeight) nY = nScreenHeight – nHeight;

MoveWindow(hwndWindow, nX, nY, nWidth, nHeight, FALSE);

return TRUE;
}

return FALSE;
}

分类: C++, 一句话 标签: ,

jsoncpp解决中文乱码问题

2015年12月13日 没有评论

衣服自己洗使用jsoncpp来解析项目中使用的json字符串,后来发现一个问题就在于jsoncpp 不支持unicode编码的中文字符。

网上搜索了一下,一种比较弱侵入性的方法如下:

打开json_tool.h文件,找到 codePointToUTF8 方法,修改 else if (cp <= 0xFFFF) 代码段里的内容,添加额外的处理。

//添加中文unicode编码
if((cp >= 0x4E00 && cp <= 0x9FA5) || (cp >= 0xF900 && cp <= 0xFA2D))
{
wchar_t src[2] = { 0 };
char dest[5] = { 0 };
src[0] = static_cast<wchar_t>(cp);
std::string local = setlocale(LC_ALL, NULL);
setlocale(LC_ALL, “chs”);
wcstombs_s(NULL, dest, 5, src, 2);
result = dest;
setlocale(LC_ALL, local.c_str());
}
//下面 else 里代码为原始代码
else
{
result.resize(3);
result[2] = static_cast<char>(0x80 | (0x3f & cp));
result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
result[0] = static_cast<char>(0xE0 | (0xf & (cp >> 12)));
}

然后重新编译即可。

分类: C++, 一句话 标签: , ,

解决spdlog无法编译的问题

2015年11月29日 没有评论

衣服自己本来是想使用log4cxx\log4cpp\log4cplus这样的库来作为日志库的,但是无论那个都无法集成,一堆的问题,于是衣服自己洗一番搜索后,发现spdlog 是一个速度非常快的C++开源库,线程安全。

这个库有一个特点就是全部都是头文件,没有cpp文件,直接引用即可。

使用VS2015添加了include文件引用后,编译报错。

错误 C2589 “(”:“::”右边的非法标记

参考了一下,发现是和系统的命名冲突,解决方法也很简单。

打开 format.h 文件,找到 int compare(BasicStringRef other) const 方法,将 std::size_t size = std::min(size_, other.size_) 修改为 std::size_t size = (std::min)(size_, other.size_),然后重新编译即可。

分类: C++, 日常 标签: ,

c++和c#相互调用dll

2015年5月5日 评论已被关闭

前不久昊问起来如何让c++和c#相互调用dll,后来专门去搜索了下,现在衣服自己洗分享出来,可能对大家有帮助。
首先我们来说c#调用c++编译的dll。这个网上已经很多了,c++里和普通写法一样,设置导出函数等等,例如c++里有一个函数 int cplusplus(int a,int b),那么在C#里,可以先申明:

[DllImport (abc.dll)]
public extern static int cplusplus(int a,int b);

然后就可以像普通的C#函数一样调用了。有几个需要注意的地方,
1、DllImport 后括号里输入c++ 的dll 的文件名,如果该dll不是在系统目录或者环境变量的目录,或者是c#程序的bin目录里,这里就应该输入完整的路径。建议放到c#的bin目录里。
2、函数必须声明为public的,不要忘记了extern关键字,当然static也所必需的。
反过来,c++是如何调用c#的dll呢,例如c#里有一个函数 public int csharp(int a,int b)在类Pipe下,而Pipe类属于ABC命名空间,那么对于c++项目,首先应该设置项目属性,打开公共语言运行时支持,即/clr标记,然后c++项目中添加c#的dll文件引用,接下来,在cpp文件里添加c#对应函数的命名空间 using namespace ABC;最后就是在需要调用的地方,使用托管代码的方式调用:

Pipe ^p = gcnew Pipe();
int a = p.csharp(3,4);

网上有同学提及编译失败,有一种可能是没有添加dll的引用,如果不喜欢添加引用,那么在cpp 文件里,使用 #using “..\Debug\csharp.dll” 也是一样可以的,不过这里就是用using,而非 include关键字,当然绝对路径也是不可少的。

现在c++和c#相互调用dll的方式就算完成了,有的同学对c++调用c#的dll的方式不太认可。为什么呢,因为要用托管代码的方式。其实上面描述的方法,本质上是使用的COM调用来完成的,微软也给出了直接COM调用的示例,喜欢这种方式的同学不妨琢磨下。

分类: C++, 日常 标签: , ,