Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
来自C#线程创建/删除的DllMain调用似乎不平衡?_C#_C_Dll_Multithreading_Native - Fatal编程技术网

来自C#线程创建/删除的DllMain调用似乎不平衡?

来自C#线程创建/删除的DllMain调用似乎不平衡?,c#,c,dll,multithreading,native,C#,C,Dll,Multithreading,Native,我正在使用一个本机用C编写的库(ANet),我正在使用C#通过我用C编写的一个小子集包装器dll与它进行接口,并静态链接到它。 该库(ANet)有一个DllMain,它只跟踪对它的引用数量(因此“进程连接”和“线程连接”计数),但它似乎是负数(即分离多于连接) 这是阿内特的德莱曼。很简单: BOOL WINAPI DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved) { static int procRefCount =

我正在使用一个本机用C编写的库(ANet),我正在使用C#通过我用C编写的一个小子集包装器dll与它进行接口,并静态链接到它。 该库(ANet)有一个DllMain,它只跟踪对它的引用数量(因此“进程连接”和“线程连接”计数),但它似乎是负数(即分离多于连接)

这是阿内特的德莱曼。很简单:

BOOL WINAPI DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
{
    static int procRefCount = 0;
    static int threadRefCount = 0;

    switch (fdwReason) {
    case DLL_PROCESS_ATTACH:
        procRefCount++;
        break;

    case DLL_PROCESS_DETACH:
        procRefCount--;
        break;

    case DLL_THREAD_ATTACH:
        threadRefCount++;
        break;

    case DLL_THREAD_DETACH:
        threadRefCount--;
        break;

    }

    if (procRefCount < 0) {
        MessageBox( NULL, "Bug - negative processes?", "DP DLL Error", MB_OK|MB_ICONERROR );
        return FALSE;
    }
    if (procRefCount > 1) {
        MessageBox( NULL, "Bug - too many processes trying to use DP", "DP DLL Error", MB_OK|MB_ICONERROR );
        return FALSE;
    }
    if (threadRefCount < 0) {
        MessageBox( NULL, "Bug - negative threads?", "DP DLL Error", MB_OK|MB_ICONERROR );
        return FALSE;
    }
    /* Only the first thread is allowed to join? */
    if (threadRefCount > 0) {
        //MessageBox( NULL, "Bug - too many threads trying to use DP", "DP DLL Error", MB_OK|MB_ICONERROR );
        return FALSE;
    }

    return(TRUE);
}
BOOL-WINAPI-DllMain(HANDLE-hModule,DWORD-fdreason,LPVOID-lpReserved)
{
静态int procRefCount=0;
静态int threadRefCount=0;
开关(FDSON){
案例DLL\u进程\u附加:
procRefCount++;
打破
案例DLL\u进程\u分离:
生产计数--;
打破
案例DLL\u线程\u连接:
threadRefCount++;
打破
案例DLL\u线程\u分离:
线程引用计数--;
打破
}
if(procRefCount<0){
MessageBox(NULL,“错误-负面进程?”,“DP DLL错误”,MB|U OK | MB|U ICONERROR);
返回FALSE;
}
如果(procRefCount>1){
MessageBox(NULL,“错误-尝试使用DP的进程太多”,“DP DLL错误”,MB_OK | MB_ICONERROR);
返回FALSE;
}
如果(threadRefCount<0){
MessageBox(NULL,“错误-负线程?”,“DP DLL错误”,MB_OK | MB_ICONERROR);
返回FALSE;
}
/*只允许第一个线程加入*/
如果(threadRefCount>0){
//MessageBox(NULL,“错误-尝试使用DP的线程太多”,“DP DLL错误”,MB_OK | MB_ICONERROR);
返回FALSE;
}
返回(真);
}
。。我的目标是不改变,这样我就不必重新编译和重新分发这个预构建的库。
因此,由于C#似乎随机创建和销毁线程,所以在我的整个程序中,DllMain被偶尔调用。 问题是,消息框中经常会显示“Bug-负面线程”


为什么THREAD\u DETACH消息比THREAD\u ATTACH消息多?

因为在DLL生存期内退出的线程比在DLL生存期内创建的线程多

线程不记得在创建DLL时出现了哪些DLL,因此在加载DLL后,每个线程都会收到一条detach消息,但只有在加载DLL后创建的线程才会收到attach消息。因此,如果创建n个线程,加载一个DLL,然后关闭这些线程,DLL将看到n
DLL\u THREAD\u DETACH
消息,但没有
DLL\u THREAD\u ATTACH
消息


由DLL决定是否对分离的线程执行任何操作,并记住它以前是否见过它;“如果DLL在TLS插槽中存储了指向已分配内存的指针,则应利用此机会释放内存。”

好的一点是,在加载DLL之前(即使是在程序加载中)可能已经创建了线程,这些线程稍后将被删除。这意味着它的正常运作,这是好的,但它仍然是一个困难的问题,我要做的solve@zeiphon我不知道库是否允许您在多线程环境中使用它(源代码中注释中的问号表示作者也不知道)。您可以通过自己调用DllMain(0,DLL\u THREAD\u ATTACH,0)数千次来增加线程计数器以避免伤害,但您可能还需要确保对DLL的所有调用都来自同一个线程,如果您使用的是.net GUI,这将更加棘手。感谢您的建议。你没有任何关于限制线程访问.NETGUI程序中DLL的信息可以告诉我吗?我不相信ANet库是线程安全的,我可能使用不当。