• 多线程CString参数传递问题


    代码如下:

       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()函数参数是传地址方式,说明地址没有传过去,后来百度一下,发现如下:

    image

    我在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: }
  • 相关阅读:
    myeclipse6.5设置智能提示
    web项目无法编译
    Duplicate property mapping of .....
    SSH常见面试题
    简易计算器JS方式实现
    js中两个感叹号的作用
    Pro Javascript Design Patterns勘误Errata汇总(持续更新中)
    Javascript简写条件语句
    js中值得推荐的Memoization
    使用au3脚本编写自动登录126邮箱
  • 原文地址:https://www.cnblogs.com/sunbing/p/3656200.html
Copyright © 2020-2023  润新知