COM and Mixed Mode DLL 
Author Message
 COM and Mixed Mode DLL

Hi...
I have an ATL COM component hosted in a Win32 DLL. I
wanted to add a managed class that can be called from the
component's methods, which causes a regsrv32 assertion in
atlbase.h. Here is how it looks:

//XmlHandler.h, XmlHandler.cpp has the definition
#using <mscorlib.dll>
#using <System.Xml.Dll>
//other using statements

__gc class CXmlHandler
{
private:
        XmlTextReader *m_reader;
        XmlTextWriter *m_writer;

public:
//other members

Quote:
};

//ManagedCodeProxy.h
#include "XmlHandler.h"

template <class T>
class CManagedCodeProxy
{
private:
      gcroot<T *> m_ManagedObject;
//other members

Quote:
};

//MyComponent.cpp
#include "ManagedCodeProxy.h"

STDMETHODIMP CMyComponent::MyMethod(BSTR XmlFileName)
{
   CManagedCodeProxy<CXmlHandler> xml;

   //use xml here to do some useful work
   return(S_OK);

Quote:
}

Now, here is a summary of what happens:
1- Both the managed class and its ManagedCodeProxy are
compiled with /clr.
2- If MyComponent.cpp is NOT compiled with /clr, that's
is an error because MyComponent.cpp indirectly includes
mscorlib.
3- If I compile MyComponent.cpp with /clr, everything
compiles and links exactly as expected, but, and here is
the catch, the component fails to register with an
assertion in ATL registration code. In other words, I
can't register a component if one of its cpp files is
compiled with /clr, which as a side effect, makes calling
gcroot from that component impossible because the /clr
would be needed. (Or am I missing something?)

Build Configuration:
1- The component is built using C++ attributes.
2- I changed my DLL to mixed mode by compiling only those
files with managed code, and those including them,
with /clr

to the linker. ALso overloadded DllUnregisterServer,
DllRegisterServer, DllGetClassObject and DllCanUnloadNow
and added the necessary __crt_dll_xxx() calls.
4- Changed the project option to not use any precompiled
header (one can't share a precompiled header between
managed and unmanaged code.)

Error Description:
1- The stack frame as a result of regsrv32 is as
following:
//top of the stack
wph.dll!ATL::CRegKey::SetStringValue(wchar_t*
pszValueName = <undefined value>, wchar_t* pszValue =
<undefined value>, unsigned __int32 dwType = 1) Line 5182
wph.dll!

//second function
ATL::CRegistryVirtualMachine::VMUpdateRegistryRecurse
(HKEY__* hKeyParent = {HKEY__}, unsigned __int32&& pOps =
0x1004e408, ATL::RGSStrings* rgStrings = 0x1004e4b0,
ATL::RGSDWORD* rgDWORDS = 0x10058388, ATL::RGSBinary*
rgBinary = 0x10058390, __int32 bRegister = 1) Line 520 +
0x81 bytes

//third function
wph.dll!ATL::CRegistryVirtualMachine::VMUpdateRegistry
(unsigned __int32* pOps = 0x1004e408, ATL::RGSStrings*
rgStrings = 0x1004e4b0, ATL::RGSDWORD* rgDWORDS =
0x10058388, ATL::RGSBinary* rgBinary = 0x10058390,
__int32 bRegister = 1) Line 258 + 0x1a bytes

//bottom of the stack
wph.dll!CProcessHandler::UpdateRegistry(__int32 bRegister
= 1) Line 105 + 0x39 bytes

2- The assertion is as a result of ATLASSERT(pszValue !=
NULL); in atlbase.h. The actual value at the time of the
function entry is <undefined>, which raises my suspicion.
It seems as a result of the /clr switch. The only valid
parameter inside ATL::CRegKey::SetStringValue() is the
dwType (DWORD), in other words, all wchar_t * parameters
show undefined value.

3- As a result, no entry in the registry is made for the
component and the component is unusable.

4- The same problem happens in release mode (without the
assertion of course.) Regsrv32 returns "DllRegisterServer
in e:\projects\wph\release\wph.dll failed.
Return code was: 0x800703e6", whcich translates
to "Invalid access to memory location.", which doen't
surprise me if the parameter is undefined.

Finally, it's worth mentioning few important points:
1- The problem is only registration related. If, for
example, I added the necessary registry entries using any
other means and run the code, the component calls into
the managed code successfully. There may be another side
effect I don't know about, though.
2- There is abosolutly no problem if any other code,
other than COM, calls into managed code inside the same
DLL.
4- I can make my COM methods call the managed classes
using CCW (COM-Callable Wrapper) but that requires the
managed code to be in separate DLL and strongly named. I
don't want either.

I simply need to call my managed class from a COM
inteface in the same DLL. Any help?

Thanks :-)

Ataa A. El-Ganayni



Sun, 23 Oct 2005 07:45:25 GMT  
 
 [ 1 post ] 

 Relevant Pages 

1. Mixed-mode dll and ASP.Net

2. mixed mode DLL causing non-continuable exception during process load

3. static initialisers in mixed-mode DLLS

4. Mixed Mode DLL Issues?

5. ATL COM dll compiles OK in debug mode, but v slow in release mod e

6. mixed mode debugger hanging

7. Mixing ATL threading modes?

8. Mixing real- and protected-mode code

9. Mixing Portrait and Landscape in Duplex mode

10. call a VB COM dll thru a C++ COM dll from a C program

11. call a VB COM dll thru a C++ COM dll from a C program

12. Mixing MFC Extension DLL's with Regular DLL's

 

 
Powered by phpBB® Forum Software