代码如下:
1: void CallThreadFun()
2: {
3: CString strPath="C:\\a.txt";
4: HANDLE hThread=::CreateThread(NULL,NULL,ThreadFunc,(LPVOID)(LPCTSTR)str,0,&thID);
5: CloseHandle(hThread);
6: }
7:
8: DWORD WINAPI ThreadFunc(LPVOID lpParam)
9: {
10: CString strPath=(LPCWSTR)lpParam;
11: doSomething(strPath);
12: ....
13: }
1.
strPath参数总是传不过去
单步跟踪到Line 10,发现CString strPath=(LPCWSTR)lpParam;strPath里没有值,CreateThread()函数参数是传地址方式,说明地址没有传过去,后来百度一下,发现如下:
我在CallThreadFun函数中定义的strPath变量时局部变量,在改函数执行玩,strPath变量所占内存便释放了,所以在线程函数ThreadFunc()中,strPath值是无法通过地址传递过去的,因为对象已经析构了。
解决办法:
1)将CallThreadFun函数中的strPath变量设成全局变量
2)将CallThreadFun函数中的strPath变量设成静态局部变量
3)在CreateThread调用下加一句WaitForSingleObject(hThread,INFINITE);不过这样似乎失去了多线程异步执行效率高的意义了。不过,需要线程同步的话就另当别论了。
4).CString *strPath= new CString(“C:\\a.txt”);在堆上分配内存,记住用完要delete。
以上两种办法都能保持程序在运行期间strPath变量一直存储在内存中,所以在ThreadFunc()函数中lpParam变量是可寻址的。
2.
关于CString转换成LPCTSTR问题。
MSDN原话如下:
--------------------------------------------------------------------------------------------------------------------------
CString objects also have the following characteristics:
- CString objects can grow as a result of concatenation operations.
- CString objects follow “value semantics.” Think of a CString object as an actual string, not as a pointer to a string.
- You can freely substitute CString objects for const char* and LPCTSTR function arguments.
- A conversion operator gives direct access to the string’s characters as a read-only array of characters (a C-style string).
Tip Where possible, allocate CString objects on the frame rather than on the heap. This saves memory and simplifies parameter passing.
--------------------------------------------------------------------------------------------------------------------------
msdn说你可以*转换CString对象为const char *和LPCTSTR类型。以下是几种传参方法。
1):使用上述转换法:
1: void CallThreadFun()
2: {
3: static CString strPath="C:\\a.txt";
4: HANDLE hThread=::CreateThread(NULL,NULL,runBatFile,(LPVOID)(LPCTSTR)strPath,0,&thID);
5: ……
6: }
7:
8: DWORD WINAPI ThreadFunc(LPVOID lpParam)
9: {
10: CString strPath=(LPCWSTR)lpParam;
11: ....
12: }
13:
2):&取地址传参
1: void CallThreadFun()
2: {
3: static CString strPath="C:\\a.txt";
4: HANDLE hThread=::CreateThread(NULL,NULL,runBatFile,&strPath,0,&thID);
5: ……
6: }
7:
8: DWORD WINAPI ThreadFunc(LPVOID lpParam)
9: {
10: CString pp=*((CString *)lpParam);
11: ....
12: }
注意:&strPath 和strPath.GetBuffer()的地址是不一样的。不能用strPath.GetBuffer()返回的地址传参,传递了以后无法解引用!
3):new 动态分配内存
1: void CallThreadFun()
2: {
3: CString *strPath=new CString("C:\\a.txt");
4: HANDLE hThread=::CreateThread(NULL,NULL,runBatFile,strPath,0,&thID);
5: ……
6: strPath=NULL;
7: }
8:
9: DWORD WINAPI ThreadFunc(LPVOID lpParam)
10: {
11: CString *lpPath=((CString *)lpParam);
12: ....
13: delete lpPath;
14: }