我写了一个win32 dynamic link library,大体如下:
int a=1;//变量a因为在fun1和fun2函数中都要用到,所以在函数体外初始化
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
}
return TRUE;
}
fun1()
{
......
}
fun2()
{
......
} 第一个线程调用dll时,将a值由1改为0。第二个线程调用dll时a的初始值就为0了。我希望第二个线程调用dll时a的初始值仍然为1,应该如何做?是不是a初始化的地方不对?高手救我!
int a=1;//变量a因为在fun1和fun2函数中都要用到,所以在函数体外初始化
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
}
return TRUE;
}
fun1()
{
......
}
fun2()
{
......
} 第一个线程调用dll时,将a值由1改为0。第二个线程调用dll时a的初始值就为0了。我希望第二个线程调用dll时a的初始值仍然为1,应该如何做?是不是a初始化的地方不对?高手救我!
解决方案 »
- VC真是恶心啊,自动代码提示都没有
- VC怎么获取一个路径下的目录和文件
- Radio关联变量
- VC6.0+ADOX: 为什么设置自动编号会出错:"多步 OLE DB 操作产生错误。如果可能,请检查每个 OLE DB 状态值。没有工作被完成。"?
- 求助,怎样在打印纸预览的界面上显示图片
- ListCtrl怎样与SQL2000连接,并能够动态的实现数据的增、删、改操作
- 用vc开发c语言时的一个问题
- ===急===急====急====大家快来看看这段代码是怎么了??
- 状态栏中显示时间为什么要调入函数OnClose()销毁定时器
- 我想发表一篇文章
- VC的对话框程序中,在对话框上面的按钮上显示图片有哪些方法??
- ie能否里的dat文件无法播放是怎么回事?
Using Thread Local Storage in a Dynamic-Link Library
ms-help://MS.MSDNQTR.v90.chs/dllproc/base/using_thread_local_storage_in_a_dynamic_link_library.htm
如果你要第二个线程调用a的初始值仍为1,那么何不每个线程load一个DLL的实例
而如果你多个线程要共同访问一个DLL实例的资源,为什么要苛求第二个线程调用a的初始值仍为1
于是用第二种方法就是tls,我这样写的,
fun1()
{
LPVOID lpvData; lpvData = TlsGetValue(dwTlsIndex);
......
}
fun2()
{
LPVOID lpvData; lpvData = TlsGetValue(dwTlsIndex);
......
}
按照我上面的这种写法是不是fun1和fun2里的lpvData指针是同一个指针?
可是我调试的时候为什么它们的地址不一样呢?我希望的是变量在fun1里更改之后,在fun2中该变量的值也同样更改。否则我之前也不会把它定义在函数体外了。
#include <windows.h>
static DWORD dwTlsIndex;int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
dwTlsIndex = TlsAlloc();
//no break;
case DLL_THREAD_ATTACH:
TlsSetValue(dwTlsIndex,LPVOID(1)); // 为每个进入的线程初始化为1
break;
case DLL_PROCESS_DETACH:
TlsFree(dwTlsIndex);
break;
case DLL_THREAD_DETACH:
break;
}
return 1;
}
//---------------------------------------------------------------------------
extern "C" void __declspec(dllexport) __stdcall SetValue(LPVOID value) // 赋值
{
TlsSetValue(dwTlsIndex,value);
}extern "C" LPVOID __declspec(dllexport) __stdcall fun1() // 取值
{
return TlsGetValue(dwTlsIndex);}
extern "C" LPVOID __declspec(dllexport) __stdcall fun2() // fun2和fun1是一样的,只是试试两个函数内调用结果是否相同
{
return TlsGetValue(dwTlsIndex);}多线程调用dll程序的代码:#include <windows.h>
#include <iostream>
#include <process.h>extern "C" void __declspec(dllimport) __stdcall SetValue(LPVOID value);
extern "C" LPVOID __declspec(dllimport) __stdcall fun1();
extern "C" LPVOID __declspec(dllimport) __stdcall fun2();using namespace std;CRITICAL_SECTION g_csCOUT; // 为cout建一个临界区,不然显示结果很乱void thread_code(void *threadno)
{
int nValue = (int)fun1();
for(int i = 0; i< 10; i++)
{
SetValue( LPVOID(++nValue) ); EnterCriticalSection(&g_csCOUT);
cout << (int)threadno << " : " << (int)fun2() << endl;
LeaveCriticalSection(&g_csCOUT);
}
}
int main(int argc, char* argv[])
{
::InitializeCriticalSection(&g_csCOUT); int nFun1Result = (int) fun1();
int nFun2Result = (int) fun2();
cout << "fun1() return :" << nFun1Result << endl;
cout << "fun2() return :" << nFun2Result << endl; // 两个结果相同,都为1 SetValue(LPVOID(1234));
nFun1Result = (int) fun1();
nFun2Result = (int) fun2();
cout << "=================================" << endl;
cout << "fun1() return :" << nFun1Result << endl;
cout << "fun2() return :" << nFun2Result << endl; // 两个结果相同,都为1234 cout << "=================================" << endl;
for(int i=0; i<5; i++)
_beginthread(thread_code,4096,(void *)i); // 建立5个线程,结果显示各个线程内的SetValue只影响此线程本身,不会互相干扰 system("pause"); ::DeleteCriticalSection(&g_csCOUT);
return 0;
}
我再检查一下我的应用程序,再试试你提供的代码。有问题再问你。多谢你!
我的fun1和fun2不在同一个线程函数里面。事实上我的要求是这样的,
我写了一个类Class,大体如下:
DWORD Class::fun() //任意一个函数
{
fun1()
......
}
DWORD Class:Thread_fun() //线程函数
{
fun2()
......
}
这个类Clss对应多个实例,我希望每个实例调用dll互不干扰。有什么办法可以实现呢?
谢谢!
不使用全局变量, 在DLL加载的时候, 去判断是否存在命名FIleMAPPING对象,没有就建立,其值为你的初始值; 如果有,其值就是你的全局变量值.
在每个线程访问的时候使用临界区读写全局变量. 在每次需要用到的地方都需要去访问这个内核对象.
效率上应该不会太低. 不过确实可以保证多线程DLL的变量共享.