concentrate on c/c++ related technology

plan,refactor,daily-build, self-discipline,

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  37 Posts :: 1 Stories :: 12 Comments :: 0 Trackbacks

常用链接

留言簿(9)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

1) 使用windows 头文件
API 头文件允许32位和64位应用程序,包含了ANSI版本和UNICODE版本的声明。
如果安装更新SDK的话,那么就可能有头文件的多个版本在机器上面。
一些函数的使用可能会通过使用条件编译代码依赖于某个特定版本的操作系统,为了编译成功,你得定义比较合适的macro.头文件使用宏来指示哪个版本系统支持编程元素。
http://msdn2.microsoft.com/en-us/library/aa383745(VS.85).aspx
2) 初始化类中的成员模板
i) 使用非模板的方式
template <typename Argtype>
class Option
{
public:
Option( void (*func_name)(Argtype), Argtype Arg1 )
  : MenuFunction<Argtype>( (*func_name)(Argtype), Argtype Arg1 )
 {
 } 
private:
 MenuFunction<Argtype> function;
};
template <typename Argtype>
Option<Argtype> makeOption(void (*func_name)(Argtype), Argtype Arg1 )
{
return Option<Argtype>(func_name, Arg1);
}

ii) 使用多态
class Option
{
private:
class FunctionBase
{
public:
virtual ~FunctionBase() {}
virtual void call() = 0;
};

template <typename Argtype>
class Function : public FunctionBase
{
public:
Function(void (*func_name)(Argtype), Argtype arg) :
m_func(func_name, arg)
{
}
void call()
{
m_func(); // or whatever
}
private:
MenuFunction<Argtype> m_func;
};

public:
template<typename Argtype> Option( void (*func_name)(Argtype), Argtype Arg1 )
{
 // of course, this means you need a destructor, copy constructor, and assignment operator
// function->call() would invoke the function
function = new Function<Argtype>(func_name, Arg1);

}  
FunctionBase * function;
};
3 大小写字符串比较大小(考虑区域性语言的问题)
#include <iostream>
#include<algorithm>
#include<functional>
#include<boost/bind.hpp>
#include<string>
#include<locale>

struct CaseSensitiveString
{
  public:
       bool operator()(const std::string & lhs,const std::string & rhs)
       {
              std::string lhs_lower;
              std::string rhs_lower;
              std::transform(lhs.begin(),lhs.end(),std::back_inserter(lhs_lower),bind(std::tolower<char>,_1,_loc));
              std::transform(rhs.begin(),rhs.end(),std::back_inserter(rhs_lower),bind(std::tolower<char>,_1,_loc));
              return lhs_lower < rhs_lower;
       }
      CaseSensitiveString(const std::locale & loc):_loc(loc){}
     private:
       std::locale _loc;
};
详细内容见:
http://learningcppisfun.blogspot.com/2008/04/case-insensitive-string-comparison.html

4 找不到msctf.h问题
在用DX自带的dxut做界面程序的时候,整个程序编制下来就出现了这个错误
fatal error C1083: Cannot open include file: 'msctf.h': No such file or directory
很诡异的,在dxsdk里面也找不到,想了很久,才发现自己没有安装platform sdk.因为win32程序之类的,最好都要安装这些sdk之类的。具体的信息可以在这里得到
http://www.gamedev.net/community/forums/topic.asp?topic_id=481358
5 重载 , 覆盖,隐藏
重载与覆盖有以下的区别:
重载:同一类,相同函数名,不同函数参数,不一定要有virtual 关键字
覆盖:子类和父类,相同函数名,  相同函数参数,一定要有virtual 关键字
隐藏:1)如果派生类的函数名与基类的函数名相同,但是参数不同,不论有无virtual关键字,基类的函数将被隐藏(与重载区别开来)
            2)如果派生类的函数名与基类的函数名相同,并且参数相同,但是基类没有virtual关键字,基类的函数将被隐藏(与覆盖区别开来)
6 快速加载文件
在游戏里面,一般对从硬盘或者DVD加载资源要求比较高的,一般采用这样的方法:

for(int i = 0; < NumBlocks; i++)
{
   // VirtualAlloc() creates storage that is page aligned
   // and so is disk sector aligned
   blocks[i] = static_cast<char *>
      (VirtualAlloc(0, BlockSize, MEM_COMMIT, PAGE_READWRITE));

   ZeroMemory(&overlapped[i], sizeof(OVERLAPPED));
   overlapped[i].hEvent = CreateEvent(0, false, false, 0);
}

HANDLE hFile = CreateFile(FileName, GENERIC_READ, 0, 0, OPEN_EXISTING,
   FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING |
   FILE_FLAG_OVERLAPPED | FILE_FLAG_SEQUENTIAL_SCAN, 0);

int iWriterPos = 0;
int iReaderPos = 0;
int iIOPos = 0;
int iPos = 0;

do
{
   while(iWriterPos - iReaderPos != NumBlocks && iIOPos < FileSize)
   {
      overlapped[iWriterPos & NumBlocksMask].Offset = iIOPos;

      int iLeft = FileSize - iIOPos;
      int iBytesToRead = iLeft > BlockSize ? BlockSize: iLeft;

      const int iMaskedWriterPos = iWriterPos & NumBlocksMask;
      ReadFile(hFile, blocks[iMaskedWriterPos], iBytesToRead, 0,
         &overlapped[iMaskedWriterPos]);

      iWriterPos++;
      iIOPos += iBytesToRead;
   }

   const int iMaskedReaderPos = iReaderPos & NumBlocksMask;

   WaitForSingleObject(overlapped[iMaskedReaderPos].hEvent, INFINITE);

   int iLeft = FileSize - iPos;
   int iBytesToRead = iLeft > BlockSize ? BlockSize: iLeft;

   memcpy(&g_buffer[iPos], blocks[iMaskedReaderPos], iBytesToRead);

   iReaderPos++;
   iPos += iBytesToRead;

}
while(iPos < FileSize);

CloseHandle(hFile);

for(int i = 0; i < NumBlocks; i++)
{
   VirtualFree(blocks[i], BlockSize, MEM_COMMIT);
   CloseHandle(overlapped[i].hEvent);
}

char* s vs char s[]
char s1[] = "abcd";// 定义一个未指定长度的char型数组,并使用字符串"abcd"将之初始化
char *s2  = "abcd";// 定义一个char型指针,并将其指向字符串"abcd",该字串位于静态存储区

s1[0] = 'm';// 无编译期、运行期错误
s2[0] = 'm';// 无编译器错误,但运行期试图修改静态内存,所以发生运行期错误
char s*只是被赋予了一个指针,char s[]是在栈中重新开辟了空间,可以在程序中写,而不引起程序崩溃。
所以相比较而言,使用字符串数组要比字符指针要安全的多,要慎用char*s 和char s[].
7 can not find MSVCR80.dll
在安装了vc2005之后,发现错误报告说MSVCR80.dll,以为又要重新安装vc2005了,但是在网络上面搜索到另外一个例子说,其实可以不用安装vc2005,直接改变配置就好了,于是就有这个了:
http://blogs.msdn.com/seshadripv/archive/2005/10/30/486985.aspx
http://www.codeguru.com/forum/showthread.php?t=439964
工程架构:
新建一个空白的 solution.
然后在新建的solution上面添加vcproject.
并且也可以在子空白solution上面添加vcproject.

1>        ]
1>正在编译资源...
1>正在链接...
1>LINK : warning LNK4075: 忽略“/INCREMENTAL”(由于“/OPT:ICF”规范)
1>fatal error C1900: Il mismatch between 'P1' version '20060201' and 'P2' version '20050411'
1>LINK : fatal error LNK1257: 代码生成失败
1>生成日志保存在“file://e:\demo-work\LocalVersionTianJi\_out\DragoonApp\Release\BuildLog.htm”
1>DragoonApp - 1 个错误,5382 个警告
========== 全部重新生成: 0 已成功, 1 已失败, 0 已跳过 ==========

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1512436&SiteID=1
http://forum.codecall.net/c-c/6244-fatal-error-c1900-il-mismatch-between-p1-version-20060201-p2-version-2005-a.html
http://www.codeguru.com/forum/archive/index.php/t-144030.html

timeGetTime: 头文件 mmsystem.h,库文件 winmm.lib
获得当前窗口的句柄。
HWND hwnd=::GetForegroundWindow();
hwnd就保存了当前系统的最顶层窗口的句柄
GetSafehWnd 取你程序所在窗口类的句柄
GetActiveWindow 取当前活动窗口句柄
AfxGetMainWnd 取主窗口句柄
GetForegroundWindow 取前台窗口句柄
FindWindow
EnumWindow
改变窗口属性:
SetWindowLong
SetClassLong.

strcpy strncpy memcpy.
strcpy:按照msdn的话说是:No overflow checking is performed when strings are copied or appended,即没有严格的长度检查,所以即使是溢出也无法被检查出来,以及The behavior of strcpy is undefined if the source and destination strings overlap.

strncpy:虽然加入了size这个来限制,但是这个size小于或者等于字符长度的话,那么该信息是不被加上字符串结束符的.并且仍旧存在跟strcpy一样的问题, The behavior of strncpy is undefined if the source and destination strings overlap

memcpy:具体的用法跟strncpy类似,也加入了size的成分在里面,但是却比strncpy好用得多.

If the source and destination overlap, this function does not ensure that the original source characters in the overlapping region are copied before being overwritten.

Use memmove to handle overlapping regions.

显然它能够处理重叠的部分,安全可靠.
并且:

The first argument, dest, must be large enough to hold count characters of src; otherwise, a buffer overrun can occur.


上次遇到的问题是我将一串汉字用strcpy来拷贝到缓冲里面,结果发现出现了乱码.
strncpy, strcpy还是建议少用,换用memcpy+memmove(如果存在重叠的情况)吧:)
未完待续.

posted on 2008-05-12 10:01 jolley 阅读(2723) 评论(1)  编辑 收藏 引用

Feedback

# re: 大杂烩 2012-04-30 21:12 陈明泽
请教:fatal error LNK1257: 代码生成失败如何解决呢?  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理