???? ??????? linker ??? ????? "?????? ?????" ?? DLL C++ ????????

?????? ????????? ?????? ?????????
???? ???????: 814472 - ??? ???????? ???? ????? ????? ??? ???????.
????? ???? | ?? ????

?? ??? ??????

???????

???? ???? ????? ????? ??????? ?? ??? ??????? ??????? ?? ?? ??? ????????:
LNK2001 ??? ????? ????
'?? ??? ???? ???????? ??? "???" '

????? linker ????? LNK4210
' ???? ???? .CRT ?? ???? ???? initializes ????? ??? ????? ?? teminators'You ???? "??????? ????" ??? ????? "?????? ?????" ?? DLL C++ ????????

????? linker ????? LNK4243
'??? ????? DLL ????? ??? ?????? ??????? ?? /clr ?? /NOENTRY; ?????? ?? ?? ???? ???? ????'.
?? ???? ??? ????????? ????? ??????? ???????:
  • ??? ????? ??? ?????? ?? / ??? ???????.
  • ????? ???? ?????? ??? ???????? ???????: ???? ???? ??? ASP.NET ";" ???? ????? ???; "??" ???? ????? ?????? Windows.
  • ??? ????? ????????? ???????? ???? ?????? ????????? ???????? ?? ?????? ?????? (??? ?? __gc ?? __value) ?? ????? ?????? ?????. ??? ???? ??????? ????? ???? ActiveX (ATL) ???? Foundation ?? Microsoft "(MFC) ? ???? ??? ??????? C (CRT)
??????: ?? ????? ????? LNK2001 LNK4210 ?? ???????? ???? ?? ????? ??????? ??????? ?? ??? ???????. ??? ??? ??????? ???? ????? ??????? ??????? ?? ??? ??????? ??? ?? LNK2001 ?? ????? LNK4210 ???? ??? ????? LNK4243 ?? ??? ??? ???????? ??????? ?????? ????? LNK4243.

?????

??? ????? ???????? ??????? ???? ??????? ??? ????? ?????? ???? (DLL) ??? ?? ??? ?????? ?????? (??? CRT ?? ATL ?? MFC) ????? ?? ????????? ???????? ?? ?????? ?????? ?? ?????? ????? ?????:
  • ???? ???? ??? ASP.NET
  • ???? ????? ?????
  • ???? ????? ?????? Windows
??? ??? ?????? ????????? ???????? ???? ?????? ????????? ???????? ?? ?????? ?????? ?? ????? ?????? ????? (??? ???? ??????? ?????? ???????? CRT ? MFC ?? ATL ????????? ????????) ? ??? ????? ????? ??? linker ?? ??? ??????? ???????. ?????? ???? ???? ??? ????? ????????? ???????? ?????? ????? ????????? ???????. ????? ?? ????????? ??? ????? ?????? ????? ???? ??? "????" ?? ??? ???????.

??????? ???? ??? ??????? ??? ?????? ????? ????? ???? ?????? "statics" ?? "????????? ???????" ?????????? ???????? ?? ??? ??????.

???? ??? ??????? ??????? ????? DLL ??????. ???? DLLs ????? (??? DLLs ???? ????? ??? ????????? ???????? ??????? ??????) ????? ?????????? ???? ???? ??? ??? ??????? ????? ?? ??????? ??? ????? ????? ??????? ????? ????? ???? ?????? ??? ?????. ?? ????? ????? ????? linker ???? ?????? ?? linker ?????? ?? ?? ??????? ??? ?????? ???? ???? ??? ??????? ???? ?? ????? ?? ??? ???????. ?????? ??? ??? ???? DLL ?????? ????? ??????? ???? whitepaper ???????:
????? ????? DLL ?????
http://msdn2.microsoft.com/en-us/library/aa290048(vs.71).aspx

????

????? ?????? ???????? C++ ???? ??? ??????? ??? ?? ??? ?????? C/C++ ?????? ??? ????? C ??? ??????? (CRT) ATL ?? MFC DLLs ????????? ?? ?????? ??? ??????? ?????. ???????? ??? ???? ???? ??????? ??????? ?? ??? ??? ?????? ???????? ?????? (DLL) ?? / NOENTRY ????? ??????.

??? ??? ??? ???????? ?? ???? ????? ????? ??????? ?????? ??? ??????? ?????? ????? DllMain ? ??? ??? (???? DllMain ?????? ??? ?????? ????? ?? ??????? ???? ????? ?????? ????? ?????).

DLL ???? ???? ????? ???? ??? ????? ?? ????? ????????? ??????? ??? ????? ???? ???? ??? ????? ?????. ????? ?? ?? ??? ??????? ????? / NOENTRY DLL.

????? ?????? MFC ATL ? CRT ???? ??? ??????? ????? ???? ????? ????? ??????? ??? ???????? ?? DLLs ??? ???? ??????? ????? ?????.

??? ????? DLL ??? ????? ???????? statics ?? ???????? ???? ????? ??? statics (??? ATL ?? MFC ?? CRT), ??? ????? DLL ????? ?? ???? ??? ????? ?? statics ??????.

?????? ?????? ??????? ???? ?????? ?? ????? ??? ??????? ???????? ??? ??? ?? DLLs ?????? ? ????? ???? ???? ???. ?????? ??? ??????? ???? ???????.

????? ???? ????? ????? ?????

  1. ???????? ?? / NOENTRY. ?? ?????? ?????? ???? ??? ?????? ?????? ??? ???? ??????? ?? ???? ??? ?????. ?? ????? ??????? ???? ?????? ???? ??? ???? "? ???? ??? ??? ???????" ? ?? ?? ?????? ??? ??????? ??? ??? ?????? ?????? ?????.
  2. ?????? msvcrt.lib. ?? ???? ?????? "????? ???????" ? ???? ??? ???? ? ???? ??? ???????. ? ?? ????? msvcrt.lib ??? ??????? ???????? ??????.
  3. ????? nochkclr.obj. ?? ???? ????? (??? ?????? ??? ?? ???? ?? ?????? ???????) ? ????? nochkclr.obj ?? ????? ???????? ??????.
  4. ?????? ?? CRT. ????? ??? ????? ???? (???? ??? ??? ?? ???? ?? ?????? ???????) ? __DllMainCRTStartup@12????? ??? ??? ???????.

    ?? ???? ??????? ???? ??????? "? ??? ??????? ??????? ????? ?? ??????:
    LINK /NOENTRY msvcrt.lib /NODEFAULTLIB:nochkclr.obj /INCLUDE:__DllMainCRTStartup@12

????? ?????? ??????? DLL ?????? Initializiation ????

??? ????? ???? ????? ???? ??? ????? ???????? ???? ?????? DLL ????? ?????? ????????? ??? ??????? ???? ??? ????? DLL ????? ??:
  • ??? ????? DLL ????? ?? ???????? ????? DLL (__declspec(dllexport)) ? ?? ???? ??????? ????? ?? ?? ??????? ??????? ?????? ??? ??????? ??? ???? ?????? ???? ???? ?? ???? DLL ????? ??.
  • DLL ????? ?? ?? DLL ???????? ??? COM.
  • ???? ??????? DLL ????? ?? ??????? ??????? ?????? ??? ??????? ? DLL ????? ?? ????? ??? ?? ????? DLL ?? ????? ???? ???????.

????? DLLs ???? ????? ????? ???????? DLL ????? ? ???????? ???? ?? ???? ??????? ??????? ???

?????? DLLs ???? ???? ???????? ???????? ????? ????? ???????? ?????? (__declspec(dllexport)) ? ??????? ?? ???? ??????? ??????? ?????? ??? ??????? ???? ??????? ???????:
  1. ????? ????? ???? ???? ??? DLL ????? ?? ??? ?? ???? ?? ????????? ???????? ???????:
    // init.cpp
    
    #include <windows.h>
    #include <_vcclrit.h>
    
    // Call this function before you call anything in this DLL.
    // It is safe to call from multiple threads; it is not reference
    // counted; and is reentrancy safe.
    
    __declspec(dllexport) void __cdecl DllEnsureInit(void)
    {
    	// Do nothing else here. If you need extra initialization steps,
    	// create static objects with constructors that perform initialization.
    	__crt_dll_initialize();
    	// Do nothing else here.
    }
    
    // Call this function after this whole process is totally done
    // calling anything in this DLL. It is safe to call from multiple
    // threads; is not reference counted; and is reentrancy safe.
    // First call will terminate.
    
    __declspec(dllexport) void __cdecl DllForceTerm(void)
    {
    	// Do nothing else here. If you need extra terminate steps, 
    	// use atexit.
    	__crt_dll_terminate();
    	// Do nothing else here.
    }
    
    ?????? ?? Visual C++ 2005 ??? ????? ??????? ??? ??? ??????? ??? ?????? ??????? ??????? ?????? (/ clr:oldSyntax) ????? ????? ????????? ???????? ?????? ?????. ?????? ??????? ??? ??? ??????? ??? ?????? ??????? ??????? ?????? ???? ??????? ???????:
    1. ???? ??? ??????? ?? ???? ??? ????? ProjectName.

      ??????ProjectName ?????? ?????? ??? ???????.
    2. ?? ?????? ????? ????? ?? ???? ??? ???.
    3. ?? ????? ??????? ???? ?????? ??? ????? ????? ?????? ??? ? ?????? ??????? (/ clr:oldSyntax) ?? ??? ????? ????? ?????? ???? ????? ??????? ???????.
    4. ???? ??? ????? ? ?? ???? ??? ?????.
    ?????? ??? ???? ?? ????????? ??? ??? ????? ????? ?????? ?????? ?????? ??????? ??????? ??? ?? ?????? ???? ?????? Microsoft Network (MSDN) ?????? ??? ?????:
    http://msdn2.microsoft.com/en-us/library/k8d11d4s.aspx
    ??? ??????? ????? ??????? ???????.
  2. ???? ?? ???? ???? DLL ??? ????????. ??? ??? ??? ???????? ?????? ?????? ???????? ???????? ??????? ??? ??? .def DLL ?? ?????? ?????:
    DllEnsureInit	PRIVATE
    DllForceTerm	PRIVATE
    
    ??? ?? ??? ?????? ??? ?????? ??? ??? ???? ????? DLLs ????? ????? ??????? ???? ????? DLL ????? ????? ????????. ?????? ???? ??????? ???? ?? ??????? ??? ???????. ?? ???? multiconsumer ?? ???????? ???? ????? ???? ???? ?? ???? DLL ????? ??.
  3. ??? ??? ???????? ???? ???? ????? DLL ? ??? ??????? DLL ???? ????? ?? ??? ??????? ?? ??? ????? ???? ?? ??????? ????? ??, ????? ???????? ???????:
    // Snippet 1
    
    typedef void (__stdcall *pfnEnsureInit)(void);
    typedef void (__stdcall *pfnForceTerm)(void);
    
    {
    	// ... initialization code
    	HANDLE hDll=::GetModuleHandle("mydll.dll");
    	If(!hDll)
    	{
    		// Exit, return; there is nothing else to do.
    	}
    	pfnEnsureInit pfnDll=::( pfnEnsureInit) GetProcAddress(hDll, 
       "DllEnsureInit");
    	if(!pfnDll)
    	{
    		// Exit, return; there is nothing else to do.
    	}
    	
    	pfnDll();
    	
    	// ... more initialization code
    }
    
  4. ??? ????????? ?????? DLL ?? ??????? ????? ?? ?????? ???????? ???????? ???????:
    // Snippet 2
    
    {
    	// ... termination code
    	HANDLE hDll=::GetModuleHandle("mydll.dll");
    	If(!hDll)
    	{
    		// exit, return; there is nothing else to do
    	}
    	pfnForceTerm pfnDll=::( pfnForceTerm) GetProcAddress(hDll, 
       "DllForceTerm");
    	if(!pfnDll)
    	{
    		// exit, return; there is nothing else to do
    	}
    	
    	pfnDll();
    	
    	// ... more termination code
    }
    
  5. ??? ???????? ??????? ???? ???? DLL ????? ????????? ???????? ??? ???:
    • ????? ????? ????????? ???????? ???????? 1 (???? ?????? 3) ?????? ??? ??? LoadLibrary ????? ???????? ??????????.
    • ????? ????? ????????? ???????? ???????? 2 (???? ?????? 4) ?????? ??? ?????? FreeLibrary DLL.

??? ????? ???????? ??? COM DLL

  • ????? ????? ??????? DLL DllCanUnloadNow ? DllGetClassObjectDllRegisterServer ? DllUnregisterServer ??? ?? ????? ?? ???????? ???????? ???????:
    //  Implementation of DLL Exports.
    
    #include <_vcclrit.h>
    
    STDAPI DllCanUnloadNow(void)
    {
        
        if ( _Module.GetLockCount() == 0 )
    	{
    		__crt_dll_terminate();
            return S_OK;
    	}
        else
        {
            return S_FALSE;
    
        }
    	
    }
    
    STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
    {
        if ( !( __crt_dll_initialize() ) )
    	{
    		return E_FAIL;
    	}
        else
        {
            return _Module.GetClassObject(rclsid, riid, ppv);
        }
    }
    
    STDAPI DllRegisterServer(void)
    {
    	if ( !( __crt_dll_initialize() ) )
    	{
    		return E_FAIL;
    	}
    	// Call your registration code here
        HRESULT hr = _Module.RegisterServer(TRUE)
     
        return hr;
    }
    
    
    STDAPI DllUnregisterServer(void)
    { 
        HRESULT hr = S_OK;
    	__crt_dll_terminate();
    
        // Call your unregistration code here
        hr = _Module.UnregisterServer(TRUE);
        return hr;
    }
    

????? DLL ???? ????? ??? ???????? ???? ??????? ????? ??????? ?????? "?" ????? DLL ?? ????? ???? ???????

?????? ??? DLL ???? ????? ??? ??????? ??????? ??????? ?????? ??? ??????? "?" ????? ???????? ?????????? ????? ?? ???? ??????? ??????? "? ???? ??????? ???????:
  1. ????? ??? ????? ???????? ????? ??? ???? ????? "?" ????? ". ????? ??? .cpp ??? ??????? ????? ?? ????? ??? ????? ?? ????? ????? ??????? ? ???????:
    // ManagedWrapper.cpp
    
    // This code verifies that DllMain is not automatically called 
    // by the Loader when linked with /noentry. It also checks some
    // functions that the CRT initializes.
    
    #include <windows.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <math.h>
    #include "_vcclrit.h"
    
    #using <mscorlib.dll>
    using namespace System;
    
    public __gc class ManagedWrapper {
    public:
    	static BOOL minitialize() {
    		BOOL retval = TRUE;
    		try {
               retval =  __crt_dll_initialize();
    		} catch(System::Exception* e) {
    			Console::WriteLine(e->Message);
    			retval = FALSE;
    		}
    		return retval;
    	}
    	static BOOL mterminate() {
    		BOOL retval = TRUE;
    		try {
                retval = __crt_dll_terminate();
    		} catch(System::Exception* e) {
    						Console::WriteLine(e->Message);
    			retval = FALSE;
    		}
    		return retval;
    	}
    };
    
    BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID 
    lpvReserved) {
    	Console::WriteLine(S"DllMain is called...");
    	return TRUE;
    } /* DllMain */
    
  2. ??????? ??? ??????? ??? ?????? ??? DLL ? ??? ???????? ?? ????????. ??????? ????? ??? ??????? ?? ????? ?? ?????:
    // Main.cpp
    
    #using <mscorlib.dll>
    using namespace System;
    using namespace System::Reflection;
    #using "ijwdll.dll";
    
    int main() {
    	int retval = ManagedWrapper::minitialize();
        ManagedWrapper::mterminate();
    }
    

?????????? Visual C++ .NET 2002

??????: ????? ????? ????? linker LNK4243 ??? ????? ?? ????? ?????? Visual C++ .NET 2002 ? ?????????? Visual C++ .NET 2002 ???? ?????? ??? ???? ????????? ???????? ?????? ??? ????? DLLs ??????.

????? ?????? Visual C++ .NET 2003 ????? ??? ??? ?????? ???? ??????? ?????? ???? ??????. ???? ?????? ???????? ?? ??? ????? ??????? ?? Visual C++ .NET 2002 ??? ????? ??? ??? ??? ??????? ????? ?? ???? _vcclrit.h ????? ??????:
/***
* _vcclrit.h
*
*       Copyright (c) Microsoft Corporation. All rights reserved.
*
* Purpose:
*       This file defines the functions and variables used by user
*       to initialize CRT and the dll in IJW scenario.
*
****/

#pragma once

#ifdef __cplusplus
extern "C" {
#endif

extern IMAGE_DOS_HEADER __ImageBase;

BOOL WINAPI _DllMainCRTStartup(
        HANDLE  hDllHandle,
        DWORD   dwReason,
        LPVOID  lpreserved
        );
#ifdef __cplusplus
}
#endif

#ifdef _cplusplus
#define __USE_GLOBAL_NAMESPACE  ::
#else
#define __USE_GLOBAL_NAMESPACE
#endif

// Used to lock 
__declspec( selectany ) LONG  volatile __lock_handle = 0;

// Init called
__declspec(selectany) BOOL volatile __initialized = FALSE;

// Term called
__declspec( selectany ) BOOL volatile __terminated = FALSE;

__inline BOOL WINAPI __crt_dll_initialize()
{
    // Try to make the variable names unique, so that the variables 
    // do not even clash with macros.
    static BOOL volatile (__retval) = FALSE;
    static DWORD volatile (__lockThreadId) = 0xffffffff;
    DWORD volatile (__currentThreadId) = __USE_GLOBAL_NAMESPACE(GetCurrentThreadId)();
    int (__int_var)=0;
    
    // Take Lock; this is needed for multithreaded scenario. 
    // Additionally, the threads need to wait here to make sure that the dll 
    // is initialized when they get past this function.
    while ( __USE_GLOBAL_NAMESPACE(InterlockedExchange)( &(__lock_handle), 1) == 1 )
	{
        ++(__int_var);
        if ((__lockThreadId) == (__currentThreadId)) 
        {
            return TRUE;
        }
		__USE_GLOBAL_NAMESPACE(Sleep)( (__int_var)>1000?100:0 );

        // If you hang in this loop, this implies that your 
        // dllMainCRTStartup is hung on another thread. 
        // The most likely cause of this is a hang in one of your 
        // static constructors or destructors.
	}
    // Note: you do not really need any interlocked stuff here because the 
    // writes are always in the lock. Only reads are outside the lock.
    (__lockThreadId) = (__currentThreadId);
    __try {
        if ( (__terminated) == TRUE )
        {
            (__retval) = FALSE;
        }
        else if ( (__initialized) == FALSE )
        {
            (__retval) = (_DllMainCRTStartup)( ( HINSTANCE )( &__ImageBase ), DLL_PROCESS_ATTACH, 0 );
            (__initialized) = TRUE;
        }

    } __finally {
        // revert the __lockThreadId
        (__lockThreadId) = 0xffffffff;
        // Release Lock
       __USE_GLOBAL_NAMESPACE(InterlockedExchange)(&(__lock_handle),0);
    }
    return (__retval);
}

__inline BOOL WINAPI __crt_dll_terminate()
{
    static BOOL volatile (__retval) = TRUE;
    static DWORD volatile (__lockThreadId) = 0xffffffff;
    DWORD volatile (__currentThreadId) = __USE_GLOBAL_NAMESPACE(GetCurrentThreadId)();
    int (__int_var)=0;
    
    // Take Lock; this lock is needed to keep Terminate 
    // in sync with Initialize.
    while ( __USE_GLOBAL_NAMESPACE(InterlockedExchange)( &(__lock_handle), 1) == 1 )
	{
        ++(__int_var);
        if ((__lockThreadId) == (__currentThreadId)) 
        {
            return TRUE;
        }
		__USE_GLOBAL_NAMESPACE(Sleep)( (__int_var)>1000?100:0 );

        // If you hang in this loop, this implies that your 
        // dllMainCRTStartup is hung on another thread. The most likely 
        // cause of this is a hang in one of your static constructors 
        // or destructors.
    }
    // Note: you do not really need any interlocked stuff here because the 
    // writes are always in the lock. Only reads are outside the lock.
    (__lockThreadId) = (__currentThreadId);
    __try {
        if ( (__initialized) == FALSE )
        {
            (__retval) = FALSE;
        }
        else if ( (__terminated) == FALSE )
        {
            (__retval) = _DllMainCRTStartup( ( HINSTANCE )( &(__ImageBase) ), DLL_PROCESS_DETACH, 0 );
            (__terminated) = TRUE;
        }
    } __finally {
        // revert the __lockThreadId
        (__lockThreadId) = 0xffffffff;
        // Release Lock
       __USE_GLOBAL_NAMESPACE(InterlockedExchange)(&(__lock_handle),0);
    }
    return (__retval);
}

?????

????? ?? ?????????? ???? ??? ??? ??????? ?????? ?????? ?? "????? ??????? ?? Microsoft:
309694BUG: ??????? AppDomainUnloaded ??? ??????? ????? ?????? ??????? Visual C++

???????

???? ???????: 814472 - ????? ??? ??????: 24/???? ??????/1428 - ??????: 7.3
????? ???
  • Microsoft Visual C++ 2005 Express Edition
  • Microsoft Visual C++ .NET 2003 Standard Edition
  • Microsoft Visual C++ .NET 2002 Standard Edition
  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.0
????? ??????: 
kbmt kbcominterop kbmanaged kbdll kbijw kbprb KB814472 KbMtar
????? ????
???: ??? ????? ??? ?????? ???????? ?????? ????? ???? ????? ?????????? ????? ?? ????????? ?????? ????. ???? ???? ?????????? ???? ?? ???????? ???????? ?????? ????????? ????? ????????? ???????? ????? ???????? ?????? ?? ?????? ??? ?? ???????? ???????? ?? ????? ??????? ?????? ??? ??????? ?????? ??. ?????? ?? ???? ??? ??????? ???????? ????? ?? ???? ????? ?????? ??? ????? ??? ????? ??????? ?? ????? ?? ?????? ??? ??? ??????? ??????? ?? ????? ????? ????? ????? ?????. ?? ????? ???? ?????????? ??????? ??? ????? ?? ??????? ?? ????? ?????? ?? ??? ????? ?? ????? ??????? ?? ???????? ?? ??? ???????. ???? ???? ?????????? ???????? ??? ????? ?????? ??????? ??????
???? ??? ????? ??????? ?????? ??????????814472

????? ???????

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com