首页
社区
课程
招聘
[旧帖] [求助]一个困扰我三天三夜的棘手问题,求高手解救 0.00雪花
发表于: 2012-7-23 18:28 2306

[旧帖] [求助]一个困扰我三天三夜的棘手问题,求高手解救 0.00雪花

2012-7-23 18:28
2306
TlsSetValue(   
      DWORD   dwTlsIndex,   
      LPVOID   lpTlsValue);就是这个函数了
初看之下第二个参数类型是LPVOID,是个指针类型,我还以为是通过要存储的变量的地址值来存储变量的值,但是看书上的程序明明是直接值传入。
书上的程序
   DWORD dwStart = ::GetTickCount();
   ::TlsSetValue(g_tlsUsedTime,(LPVOID)dwStart);
GetTickCount()返回的是启动的时间,单位是毫秒,是一个32位的整数,又不是地址值。
这样靠强制转换不是很别扭吗。
我觉得应该是这样   DWORD dwStart = ::GetTickCount();
   ::TlsSetValue(g_tlsUsedTime,(LPVOID()&dwStart));
或这样
   DWORD *dwStart;  *dwStart=::GetTickCount();
   ::TlsSetValue(g_tlsUsedTime,(LPVOID)dwStart);
还有这段代码
dwElapsed = dwElapsed - (DWORD)::TlsGetValue(g_tlsUsedTime);

TlsGetValue函数的返回值明明是LPVOID类型啊,怎么可以把一个指针强制转换成DWORD,怪啊

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
书上原程序
///////////////////////////////////////////////////////////////
// 02UseTLS.cpp.cpp文件

#include <stdio.h>
#include <windows.h>
#include <process.h>

// 利用TLS记录线程的运行时间

DWORD g_tlsUsedTime;
void InitStartTime();
DWORD GetUsedTime();

UINT __stdcall ThreadFunc(LPVOID)
{
        int i;

        // 初始化开始时间
        InitStartTime();

        // 模拟长时间工作
        i = 10000*10000;
        while(i--) { }

        // 打印出本线程运行的时间
        printf(" This thread is coming to end. Thread ID: %-5d, Used Time: %d \n",
                                                ::GetCurrentThreadId(), GetUsedTime());
        return 0;
}

int main(int argc, char* argv[])
{
        UINT uId;
        int i;
        HANDLE h[10];

        // 通过在进程位数组中申请一个索引,初始化线程运行时间记录系统
        g_tlsUsedTime = ::TlsAlloc();

        // 令十个线程同时运行,并等待它们各自的输出结果
        for(i=0; i<10; i++)
        {
                h[i] = (HANDLE)::_beginthreadex(NULL, 0, ThreadFunc, NULL, 0, &uId);
        }
        for(i=0; i<10; i++)
        {
                ::WaitForSingleObject(h[i], INFINITE);
                ::CloseHandle(h[i]);
        }

        // 通过释放线程局部存储索引,释放时间记录系统占用的资源
        ::TlsFree(g_tlsUsedTime);
        return 0;
}

// 初始化线程的开始时间
void InitStartTime()
{
        // 获得当前时间,将线程的创建时间与线程对象相关联
        DWORD dwStart = ::GetTickCount();

        ::TlsSetValue(g_tlsUsedTime, (LPVOID)dwStart);
}

// 取得一个线程已经运行的时间
DWORD GetUsedTime()
{
        // 获得当前时间,返回当前时间和线程创建时间的差值
        DWORD dwElapsed = ::GetTickCount();
        dwElapsed = dwElapsed - (DWORD)::TlsGetValue(g_tlsUsedTime);
        return dwElapsed;
}
2012-7-23 18:29
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
这个C的基础问题。。。好好看看C语言吧。
2012-7-23 20:27
0
雪    币: 8
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
其实有几点:明白了就行:
1:指针也是个32位的数.(int * a = 0x0040000;就是存的数嘛!)
2:LPVOID这个更能概括要存储的值.肯定是有无符号的,又有是有符号的,(就是说,设计者也不知道你到底要存什么,所以就通杀了,这个函数内它就是存一个数,不会间接使用的,你放心!).
3:lpTlsValue,它只是你要保存的东西,你要存啥就存啥!

TlsSetValue(   
      DWORD   dwTlsIndex,   
      LPVOID   lpTlsValue);

example:
1:
int * b = 0x00400000;
unsigned long a = 0;
TlsSetValue(a,(LPVOID)b);//强制转换是为了能编译过去,没有特别的.
2:
int  b = 0x00400000;
unsigned long a = 0;
TlsSetValue(a,(LPVOID)b);//强制转换是为了能编译过去,没有特别的.

都是在a位置存个数是0x00400000;
2012-7-26 17:25
0
雪    币: 15
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
TlsSetValue(   
      DWORD   dwTlsIndex,   
      LPVOID   lpTlsValue);

lpTlsValue参数,本来给的是一个用LocalAlloc分配的存储空间。在例子中,因为只需要存一个DWORD,刚好在32位下指针也是DWORD长度,所以就直接拿那个指针存了这个值。(本来指针是拿来存一个指向的内存区域的地址,这里拿来存一个值,所以这个指针指向的也就是无效的。)
2012-7-26 19:26
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
2012-7-27 13:46
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
如果这么运行没问题,解释就是4楼的;
如果出问题了,解释采用5楼的;
API解释:
[in]   Pointer   to   the   value   to   be   stored   in   the   calling   thread 's   TLS   slot   specified   by   dwTlsIndex.  
貌似字面上5楼正解。
追根要看这个API的函数实现了。
所以,要这样执行这个函数执行没啥问题,个人感觉拿4楼的解释自我安慰下也可以
2012-7-27 18:15
0
雪    币: 33
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
代码关键是看什么人写,在什么场合用,和作者的素质习惯和使用场景关系比较大
2012-7-28 10:07
0
游客
登录 | 注册 方可回帖
返回
//