Solved

C++  to  C#

Posted on 2007-03-18
52
1,355 Views
Last Modified: 2008-01-09
I have 2 small VC++ files,  created using VS 6.0

EventHandler.h
EventHandler.cpp

Total lines of code is less than 130.   I want to convert them to C# .Net.      

One C++ programmer has already told me the following:  "I've taken a brief look at your files and I don't think there is a straight-forward way to convert these to C#.  The multiple inheritance alone would be sufficient to prevent a clear translation (since C# doesn't allow multiple inheritance)."

Can someone give it a shot at converting this C++ code to C#?      If not, what are my options?   Build a dll to be called from C# .Net ?   Wrapping the files classes / methods using Managed C++ in order to call from C# .Net ?

They are not large files.   Here are the files below:     first file is EventHandler.h ,  second file is EventHandler.cpp   ...

=====================================================

// EvenHandler.h : Declaration of the CEventHandler

#ifndef __EVENTHANDLER_H_
#define __EVENTHANDLER_H_

#include "resource.h"       // main symbols


struct HandleEvent
{
      virtual void Event( IDispatch * pISrc, BSTR bstrSymbol, BSTR bstrHint, IDispatch * pIEventData) = 0 ;
};

class GBQuoteEventHandler
{
public:
      virtual bool            Initialize( HandleEvent* pEventHandler, IUnknown* pISrc, IID& iid )            = 0 ;
      virtual void            Uninitialize( void )                                                                              = 0 ;
};

class GBQuoteEventHandlerDef : public GBQuoteEventHandler
{
public:
      GBQuoteEventHandlerDef() ;
      virtual ~GBQuoteEventHandlerDef() ;

      bool            Initialize( HandleEvent* pEventHandler, IUnknown* pISrc, IID& iid ) ;
      void            Uninitialize( void ) ;

      struct Impl;

private:
      Impl* m_pImpl;

};

#endif //__EVENTHANDLER_H_


=====================================================

// EvenHandler.cpp : Implementation of CEventHandler
#include "stdafx.h"
#include "EventHandler.h"

struct GBQuoteEventHandlerDef::Impl:
      public CComObjectRoot,
      public GBQUOTESLib::IGBQuoteEventVtbl
{
public:
      Impl() ;
      ~Impl() ;

      HandleEvent*            m_pEventHandler ;

      CComPtr<IUnknown>      m_spISrc ;
      IID                              m_IID ;
      DWORD                        m_dwCookie ;

      bool                        Initialize( HandleEvent* pEventHandler, IUnknown* pISrc, IID& iid  ) ;
      void                        Uninitialize() ;

BEGIN_COM_MAP(GBQuoteEventHandlerDef::Impl)
      COM_INTERFACE_ENTRY(GBQUOTESLib::IGBQuoteEventVtbl)
END_COM_MAP()

// IEventHandler

// IGBQuoteEventVtbl
      STDMETHOD(raw_GBEvent)(IDispatch * pISrc, BSTR bstrSymbol, BSTR bstrHint, IDispatch * pIEventData) ;
};

GBQuoteEventHandlerDef::Impl::Impl()
{
}
GBQuoteEventHandlerDef::Impl::~Impl()
{
      Uninitialize() ;
}

STDMETHODIMP GBQuoteEventHandlerDef::Impl::raw_GBEvent(IDispatch * pISrc, BSTR bstrSymbol, BSTR bstrHint, IDispatch * pIEventData)
{
      m_pEventHandler->Event( pISrc, bstrSymbol, bstrHint, pIEventData ) ;
      return S_OK ;
}

bool GBQuoteEventHandlerDef::Impl::Initialize( HandleEvent* pEventHandler, IUnknown* pISrc, IID& iid  )
{
      m_pEventHandler      = pEventHandler ;
      m_spISrc            = pISrc  ;
      m_IID                  = iid ;

      HRESULT rc =      AtlAdvise( pISrc, GetUnknown(), iid, &m_dwCookie);

      return true ;
}

void GBQuoteEventHandlerDef::Impl::Uninitialize(void)
{
      if( m_dwCookie )
      {
            HRESULT rc =      AtlUnadvise( m_spISrc, m_IID, m_dwCookie);

            m_dwCookie = 0 ;
      }
}

/////////////////////////////////////////////////////////////////////////////////

GBQuoteEventHandlerDef::GBQuoteEventHandlerDef()      : m_pImpl( new CComObject<GBQuoteEventHandlerDef::Impl> )
{
}
GBQuoteEventHandlerDef::~GBQuoteEventHandlerDef()      
{
}

bool GBQuoteEventHandlerDef::Initialize( HandleEvent* pEventHandler, IUnknown* pISrc, IID& iid  )
{
      return m_pImpl->Initialize( pEventHandler, pISrc, iid ) ;
}
void GBQuoteEventHandlerDef::Uninitialize( void )
{
      m_pImpl->Uninitialize() ;
}


0
Comment
Question by:lblinc
  • 33
  • 18
52 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 18745994
This is embedded into the ATL framework which will make it even harder to port - any chance you can leave that C++ and call it using COM/Interop?
0
 

Author Comment

by:lblinc
ID: 18746034
Yes, I'm open to use COM/Interop, but to be honest..  I'm not very familiar with building DLLs that can then be reg'd and referenced from within VS .Net 2005       Maybe you can help me to build a DLL with these 2 files in it ?

I do have all the project source code and headers of the other files that use these 2 files:   EventHandler.h  EventHandler.cpp     But it is currently not a library (DLL) project, rather it's just a sample application project that includes these 2 files..

So I guess I would need some direction on how to successfully build a COM DLL that I would then need to be referenced from within  .Net  env

I do not know what effort is involved to create and build the DLL,  including use of exporting functions / methods..  etc..   ??  
0
 
LVL 86

Expert Comment

by:jkr
ID: 18746050
To be honest, I doubt that this is all you need. Just not enogh code, it seems that either some other source files or a library is needed to compile that to a working DLL. First of all, there's no reference to the ATL header files in the above code, yet it uses ATL specific constructs - thus it seems incomplete.

If it wasn't, it should be as easy as creating a new ATL project and adding these files.
0
 

Author Comment

by:lblinc
ID: 18746131
jkr,  I do have all the compiled files for the VC++ sample app...  The entire compiled app project headers / source is less than 15 files total.     EventHandler.h  EventHandler.cpp   files  are just 2  (out of 10 or so)  files...  

Actually, I already attempted to create a new ATL project and added all the compiled project files, including EventHandler.h   and   EventHandler.cpp ,  however I wasn't able to successfully  reg the new DLL  and then also wasn't able to reference it from Visual Studio .Net 2005

Again,  I don't have much experience with building DLLs with Visual Studio 6.0    Any help appreciated.
0
 
LVL 86

Expert Comment

by:jkr
ID: 18746138
If you have all the files, I wonder if there is a .sln or .vcproj file around - with these, you could just open the project and compile it to a working binary. Registering it then is just

regsvr32 mydll.dll
0
 

Author Comment

by:lblinc
ID: 18746145
I'm not that familiar with ..    Application Settings, ATL Project Wizard.    Or referencing the DLL and functions..   whether the functions / methods need to be exported, etc..
 
http://msdn2.microsoft.com/en-us/library/0513eb2h(VS.80).aspx  
0
 

Author Comment

by:lblinc
ID: 18746152
I have the project open..  everything compiles fine...   it creates the .exe  no problems..

GBQuotesCln.exe - 0 error(s), 0 warning(s)

>  you could just open the project and compile it to a working binary.

How do I do this exactly?    Is it really that easy ??

0
 
LVL 86

Expert Comment

by:jkr
ID: 18746173
>> >  you could just open the project and compile it to a working binary.
>>How do I do this exactly?    Is it really that easy ??

You just did it - so: Yes ;o)
0
 
LVL 86

Expert Comment

by:jkr
ID: 18746180
And now to the next step: http://msdn2.microsoft.com/en-us/library/ms173184(VS.80).aspx ("Interoperability (C# Programming Guide) ")
0
 

Author Comment

by:lblinc
ID: 18746186
Ok.   This is my first time using the ATL COM AppWizard to create a DLL in VS 6.0.    Let me absorb things for a bit, then get back to you on my progress.  
0
 

Author Comment

by:lblinc
ID: 18748306
jkr  ~   I'm stuck.   You mentioned that I should just open up the original project app,  then compile it directly to a DLL.      How exactly is that done?    ATL COM AppWizard  ?

My app compiles fine as an .exe,  but when I try to copy / merge files using COM AppWizard (with the new DLLEntry Point info in the main .cpp ..)  in order to build a DLL, there are errors all around.    What am i missing here?   Shouldn't I just be able to open my project, and directly complie it to a DLL ??
0
 
LVL 86

Expert Comment

by:jkr
ID: 18748479
>>How exactly is that done?

Just like you just did it - open the project and choose 'Build'. No need to set up a new project.
0
 

Author Comment

by:lblinc
ID: 18748609
Please understand..   It is NOT a dll project in its current state..  .    It is an application..  a sample MFC based COM VC++ application with a GUI.    

Thus,  to "Build" it creates an  .EXE output,  not a DLL ...    
0
 
LVL 86

Expert Comment

by:jkr
ID: 18748681
Ah, now I got it. Hm, the you could try to edit the project file manually. Open the .dsp file in a text editor and change all the occurrances of 'myfile.exe' to 'myfile.dll'. Then, locate the lines that start with

# ADD LINK32

(there are two) and add '/DLL' at the end. Then, save and rebuild.
0
 

Author Comment

by:lblinc
ID: 18748778
In the text editor on the .dsp..     Instead of 'myfile.exe'  ..    it appears as follows in most places..

!MESSAGE "myfile - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "myfile - Win32 Debug" (based on "Win32 (x86) Application")

So there isn't any '.exe' extension on anything in the editor ??    How to change to .dll  ??
0
 

Author Comment

by:lblinc
ID: 18748796
Here are the ADD LINK32  statements from the editor...

# ADD LINK32 /nologo /subsystem:windows /machine:I386

# ADD LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
0
 

Author Comment

by:lblinc
ID: 18748812
Actually, here's the entire text ...

# Microsoft Developer Studio Project File - Name="GBQuotesCln" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **

# TARGTYPE "Win32 (x86) Application" 0x0101

CFG=GBQuotesCln - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "GBQuotesCln.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "GBQuotesCln.mak" CFG="GBQuotesCln - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "GBQuotesCln - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "GBQuotesCln - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE

# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe

!IF  "$(CFG)" == "GBQuotesCln - Win32 Release"

# PROP BASE Use_MFC 6
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 6
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /FD /c
# SUBTRACT CPP /Fr
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
# ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
# ADD LINK32 /nologo /subsystem:windows /machine:I386
# SUBTRACT LINK32 /debug

!ELSEIF  "$(CFG)" == "GBQuotesCln - Win32 Debug"

# PROP BASE Use_MFC 6
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 6
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept

!ENDIF

# Begin Target

# Name "GBQuotesCln - Win32 Release"
# Name "GBQuotesCln - Win32 Debug"
# Begin Group "Source Files"

# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File

SOURCE=.\EventHandler.cpp
# End Source File
# Begin Source File

SOURCE=.\GBQuotesCln.cpp
# End Source File
# Begin Source File

SOURCE=.\GBQuotesCln.rc
# End Source File
# Begin Source File

SOURCE=.\GBQuotesClnDlg.cpp
# End Source File
# Begin Source File

SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
# Begin Source File

SOURCE=.\StkDlg.cpp
# End Source File
# Begin Source File

SOURCE=.\SymbolProcessor.cpp
# End Source File
# End Group
# Begin Group "Header Files"

# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File

SOURCE=.\EventHandler.h
# End Source File
# Begin Source File

SOURCE=.\GBQuotesCln.h
# End Source File
# Begin Source File

SOURCE=.\GBQuotesClnDlg.h
# End Source File
# Begin Source File

SOURCE=.\Resource.h
# End Source File
# Begin Source File

SOURCE=.\StdAfx.h
# End Source File
# Begin Source File

SOURCE=.\StkDlg.h
# End Source File
# Begin Source File

SOURCE=.\SymbolProcessor.h
# End Source File
# End Group
# Begin Group "Resource Files"

# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File

SOURCE=.\Eventhandler.rgs
# End Source File
# Begin Source File

SOURCE=.\res\gbquotes.bin
# End Source File
# Begin Source File

SOURCE=.\res\GBQuotesCln.ico
# End Source File
# Begin Source File

SOURCE=.\res\GBQuotesCln.rc2
# End Source File
# Begin Source File

SOURCE=.\GBQuotesCln.rgs
# End Source File
# End Group
# Begin Source File

SOURCE=.\ReadMe.txt
# End Source File
# End Target
# End Project
# Section GBQuotesCln : {001A001A-0513-0000-1274-002000000000}
#       1:16:IDR_GBQUOTESCLN1:105
# End Section
0
 
LVL 86

Expert Comment

by:jkr
ID: 18748858
>>How to change to .dll  ??

By adding '/DLL' to the '# ADD LINK32' lines as mentioned above. Sometimes the .exe name is present in the project file to specify a certain output file name, thus the check. Adding '/DLL' means:

/DLL   (Build a DLL)

This option builds a DLL as the main output file.
0
 

Author Comment

by:lblinc
ID: 18748934
Ok.  That worked..   Now i have the 2 files in the DEBUG dir ..    finally!    

GBQuotesCln.exe   213 KB    Application
GBQuotesCln.dll      213 KB    Application Extension

I had a feeling that I would not be able to register the file:   Message:      This file can not be reg'd.

So I still need to ad DllRegisterServer,  DLLEntryPoint  info to this project  ??
0
 

Author Comment

by:lblinc
ID: 18749040
As expected, when trying to reference from .Net 2003  -->

A reference for the DLL could not be added when trying to add to another VS 2003 project.   This is not a valid assembly or COM component.     Only assemblies with extension 'dll' and 'COM' components can be refereneced.      Please make sure that the file is accessible and that its' a valid assembly or COM component.

So, that is interesting info you suggested to add the /DLL  and  edit the .dsp   ,  but still need to reference..    

My issue now is..

1)    Do I create a New DLL project on the side using ATL Wizard, and then try to merge some of the DLLEntry  info  in to the main   .cpp file  from my project?
0
 
LVL 86

Expert Comment

by:jkr
ID: 18749109
>>So I still need to ad DllRegisterServer,  DLLEntryPoint  info to this project  ??

'DllRegisterServer()' is mandantory, the entry point isn't. Actually, the code should already include all the necessary registration functions, though they probably are not exported. If you can locate these, exporting 'DllRegisterServer()' and 'DllUnRegisterServer()' should get you started.
0
 

Author Comment

by:lblinc
ID: 18749265
>>  Actually, the code should already include all the necessary registration functions, though they probably are not exported.

I do not think this is true..   to stress again that this was previously an Application .exe,  and  not a  .dll  project from the start.    In other words,  this project was never meant to be a dll, or have need to export any functions.    It had no reason for that as it previously existed.  Although, It's my interest to transform it to a callable dll so that I can call some of the methods from .Net

Anyway, below is code from the ATL Wizard for creating a new DLL project.    And there is also a ".def" file that i see.    Here is the ATL Wizard code that's generated when creating GBQuotesCln.cpp

// GBQuotesCln.cpp : Implementation of DLL Exports.


// Note: Proxy/Stub Information
//      To build a separate proxy/stub DLL,
//      run nmake -f GBQuotesClnps.mk in the project directory.

#include "stdafx.h"
#include "resource.h"
#include <initguid.h>
#include "GBQuotesCln.h"

#include "GBQuotesCln_i.c"


CComModule _Module;

BEGIN_OBJECT_MAP(ObjectMap)
END_OBJECT_MAP()

/////////////////////////////////////////////////////////////////////////////
// DLL Entry Point

extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        _Module.Init(ObjectMap, hInstance, &LIBID_GBQUOTESCLNLib);
        DisableThreadLibraryCalls(hInstance);
    }
    else if (dwReason == DLL_PROCESS_DETACH)
        _Module.Term();
    return TRUE;    // ok
}

/////////////////////////////////////////////////////////////////////////////
// Used to determine whether the DLL can be unloaded by OLE

STDAPI DllCanUnloadNow(void)
{
    return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
}

/////////////////////////////////////////////////////////////////////////////
// Returns a class factory to create an object of the requested type

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
    return _Module.GetClassObject(rclsid, riid, ppv);
}

/////////////////////////////////////////////////////////////////////////////
// DllRegisterServer - Adds entries to the system registry

STDAPI DllRegisterServer(void)
{
    // registers object, typelib and all interfaces in typelib
    return _Module.RegisterServer(TRUE);
}

/////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registry

STDAPI DllUnregisterServer(void)
{
    return _Module.UnregisterServer(TRUE);
}
0
 

Author Comment

by:lblinc
ID: 18749279
And..   there is also a '.def' file, as follows:     Should these files somehow be added to my DLL project ?

; GBQuotesCln.def : Declares the module parameters.

LIBRARY      "GBQuotesCln.DLL"

EXPORTS
      DllCanUnloadNow     @1 PRIVATE
      DllGetClassObject   @2 PRIVATE
      DllRegisterServer   @3 PRIVATE
      DllUnregisterServer      @4 PRIVATE
0
 
LVL 86

Expert Comment

by:jkr
ID: 18749316
>>to stress again that this was previously an Application .exe,  and  not a  .dll  
>>project from the start.  

Yes, but also an ATL server in an executable needs to be registered, so the code should already be somewhere, yet not in functions called 'DllRegisterServer()' etc.

If you don't care about the old CLSID, you should be fine by adding the newly generated code to the converted project.
0
 

Author Comment

by:lblinc
ID: 18749409

>>  'DllRegisterServer()' is mandantory, the entry point isn't. Actually, the code should already include all the necessary registration functions, though they probably are not exported. If you can locate these, exporting 'DllRegisterServer()' and 'DllUnRegisterServer()' should get you started.

Ok.  i actually got it to build successfully, but only without the entry point block..    

Deleting intermediate files and output files for project 'GBQuotesCln - Win32 Debug'.
--------------------Configuration: GBQuotesCln - Win32 Debug--------------------
Compiling resources...
Compiling...
StdAfx.cpp
Compiling...
EventHandler.cpp
GBQuotesCln.cpp
GBQuotesClnDlg.cpp
StkDlg.cpp
SymbolProcessor.cpp
Generating Code...
Linking...
   Creating library Debug/GBQuotesCln.lib and object Debug/GBQuotesCln.exp

GBQuotesCln.dll - 0 error(s), 0 warning(s)
0
 

Author Comment

by:lblinc
ID: 18749477
jkr:     I did find this code in the main .cpp of the project..   I just decided to remove the added DLL related functions because i found this code below,  but not sure what to do with it yet ...


CGBQuotesClnModule _Module;

BEGIN_OBJECT_MAP(ObjectMap)
END_OBJECT_MAP()

LONG CGBQuotesClnModule::Unlock()
{
      AfxOleUnlockApp();
      return 0;
}

LONG CGBQuotesClnModule::Lock()
{
      AfxOleLockApp();
      return 1;
}
LPCTSTR CGBQuotesClnModule::FindOneOf(LPCTSTR p1, LPCTSTR p2)
{
      while (*p1 != NULL)
      {
            LPCTSTR p = p2;
            while (*p != NULL)
            {
                  if (*p1 == *p)
                        return CharNext(p1);
                  p = CharNext(p);
            }
            p1++;
      }
      return NULL;
}


int CGBQuotesClnApp::ExitInstance()
{
      if (m_bATLInited)
      {
            _Module.RevokeClassObjects();
            _Module.Term();
            CoUninitialize();
      }

      return CWinApp::ExitInstance();

}

BOOL CGBQuotesClnApp::InitATL()
{
      m_bATLInited = TRUE;

#if _WIN32_WINNT >= 0x0400
      HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
#else
      HRESULT hRes = CoInitialize(NULL);
#endif

      if (FAILED(hRes))
      {
            m_bATLInited = FALSE;
            return FALSE;
      }

      _Module.Init(ObjectMap, AfxGetInstanceHandle());
      _Module.dwThreadID = GetCurrentThreadId();

      LPTSTR lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT
      TCHAR szTokens[] = _T("-/");

      BOOL bRun = TRUE;
      LPCTSTR lpszToken = _Module.FindOneOf(lpCmdLine, szTokens);
      while (lpszToken != NULL)
      {
            if (lstrcmpi(lpszToken, _T("UnregServer"))==0)
            {
                  _Module.UpdateRegistryFromResource(IDR_GBQUOTESCLN1, FALSE);
                  _Module.UnregisterServer(TRUE); //TRUE means typelib is unreg'd
                  bRun = FALSE;
                  break;
            }
            if (lstrcmpi(lpszToken, _T("RegServer"))==0)
            {
                  _Module.UpdateRegistryFromResource(IDR_GBQUOTESCLN1, TRUE);
                  _Module.RegisterServer(TRUE);
                  bRun = FALSE;
                  break;
            }
            lpszToken = _Module.FindOneOf(lpszToken, szTokens);
      }

      if (!bRun)
      {
            m_bATLInited = FALSE;
            _Module.Term();
            CoUninitialize();
            return FALSE;
      }

      hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
            REGCLS_MULTIPLEUSE);
      if (FAILED(hRes))
      {
            m_bATLInited = FALSE;
            CoUninitialize();
            return FALSE;
      }      

      return TRUE;

}

0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 86

Accepted Solution

by:
jkr earned 400 total points
ID: 18749634
Oh, that looks good - you can then just add

/////////////////////////////////////////////////////////////////////////////
// Used to determine whether the DLL can be unloaded by OLE

extern "C" __declspec(dllexport)
STDAPI DllCanUnloadNow(void)
{
    return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
}

/////////////////////////////////////////////////////////////////////////////
// Returns a class factory to create an object of the requested type

extern "C" __declspec(dllexport)
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
    return _Module.GetClassObject(rclsid, riid, ppv);
}

/////////////////////////////////////////////////////////////////////////////
// DllRegisterServer - Adds entries to the system registry

extern "C" __declspec(dllexport)
STDAPI DllRegisterServer(void)
{
    // registers object, typelib and all interfaces in typelib
    return _Module.RegisterServer(TRUE);
}

/////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registry

extern "C" __declspec(dllexport)
STDAPI DllUnregisterServer(void)
{
    return _Module.UnregisterServer(TRUE);
}

"as is" to the code you posted above.
0
 

Author Comment

by:lblinc
ID: 18749653
jkr:     What do you think if i try to  extern "C"  this function...      BOOL CGBQuotesClnApp::InitATL()  from above  ???

Will that help me to reg the dll ?
0
 
LVL 86

Expert Comment

by:jkr
ID: 18749706
No, you cannot export member functions of a class that way. And having 'DllRegisterServer()' et. al. is mandantory anyway. I would not mess to musch with the existing code, just add what's necessary.
0
 

Author Comment

by:lblinc
ID: 18749714
This is the existing code for   GBQuotesCln.cpp      

// GBQuotesCln.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "GBQuotesCln.h"
#include "GBQuotesClnDlg.h"
#include <initguid.h>

#include "Eventhandler.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


/////////////////////////////////////////////////////////////////////////////
// CGBQuotesClnApp

BEGIN_MESSAGE_MAP(CGBQuotesClnApp, CWinApp)
      //{{AFX_MSG_MAP(CGBQuotesClnApp)
            // NOTE - the ClassWizard will add and remove mapping macros here.
            //    DO NOT EDIT what you see in these blocks of generated code!
      //}}AFX_MSG
      ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGBQuotesClnApp construction

CGBQuotesClnApp::CGBQuotesClnApp()
{
      // TODO: add construction code here,
      // Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CGBQuotesClnApp object

CGBQuotesClnApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CGBQuotesClnApp initialization

BOOL CGBQuotesClnApp::InitInstance()
{
      

      if (!InitATL())
            return FALSE;

      AfxEnableControlContainer();

      CCommandLineInfo cmdInfo;
      ParseCommandLine(cmdInfo);

      if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated)
      {
            return TRUE;
      }



      if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated)
      {
            return TRUE;
      }



      HRESULT hr=CoInitialize(NULL);

      if(FAILED(hr))
            AfxMessageBox("Com library not initialised!");

      // Standard initialization
      // If you are not using these features and wish to reduce the size
      //  of your final executable, you should remove from the following
      //  the specific initialization routines you do not need.

#ifdef _AFXDLL
      Enable3dControls();                  // Call this when using MFC in a shared DLL
#else
      Enable3dControlsStatic();      // Call this when linking to MFC statically
#endif

      CGBQuotesClnDlg dlg;
      m_pMainWnd = &dlg;
      int nResponse = dlg.DoModal();
      if (nResponse == IDOK)
      {
            // TODO: Place code here to handle when the dialog is
            //  dismissed with OK
      }
      else if (nResponse == IDCANCEL)
      {
            // TODO: Place code here to handle when the dialog is
            //  dismissed with Cancel
      }

      // Since the dialog has been closed, return FALSE so that we exit the
      //  application, rather than start the application's message pump.
      return FALSE;
}

      

      
CGBQuotesClnModule _Module;

BEGIN_OBJECT_MAP(ObjectMap)
END_OBJECT_MAP()

LONG CGBQuotesClnModule::Unlock()
{
      AfxOleUnlockApp();
      return 0;
}

LONG CGBQuotesClnModule::Lock()
{
      AfxOleLockApp();
      return 1;
}
LPCTSTR CGBQuotesClnModule::FindOneOf(LPCTSTR p1, LPCTSTR p2)
{
      while (*p1 != NULL)
      {
            LPCTSTR p = p2;
            while (*p != NULL)
            {
                  if (*p1 == *p)
                        return CharNext(p1);
                  p = CharNext(p);
            }
            p1++;
      }
      return NULL;
}


int CGBQuotesClnApp::ExitInstance()
{
      if (m_bATLInited)
      {
            _Module.RevokeClassObjects();
            _Module.Term();
            CoUninitialize();
      }

      return CWinApp::ExitInstance();

}


BOOL CGBQuotesClnApp::InitATL()
{
      m_bATLInited = TRUE;

#if _WIN32_WINNT >= 0x0400
      HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
#else
      HRESULT hRes = CoInitialize(NULL);
#endif

      if (FAILED(hRes))
      {
            m_bATLInited = FALSE;
            return FALSE;
      }

      _Module.Init(ObjectMap, AfxGetInstanceHandle());
      _Module.dwThreadID = GetCurrentThreadId();

      LPTSTR lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT
      TCHAR szTokens[] = _T("-/");

      BOOL bRun = TRUE;
      LPCTSTR lpszToken = _Module.FindOneOf(lpCmdLine, szTokens);
      while (lpszToken != NULL)
      {
            if (lstrcmpi(lpszToken, _T("UnregServer"))==0)
            {
                  _Module.UpdateRegistryFromResource(IDR_GBQUOTESCLN1, FALSE);
                  _Module.UnregisterServer(TRUE); //TRUE means typelib is unreg'd
                  bRun = FALSE;
                  break;
            }
            if (lstrcmpi(lpszToken, _T("RegServer"))==0)
            {
                  _Module.UpdateRegistryFromResource(IDR_GBQUOTESCLN1, TRUE);
                  _Module.RegisterServer(TRUE);
                  bRun = FALSE;
                  break;
            }
            lpszToken = _Module.FindOneOf(lpszToken, szTokens);
      }

      if (!bRun)
      {
            m_bATLInited = FALSE;
            _Module.Term();
            CoUninitialize();
            return FALSE;
      }

      hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
            REGCLS_MULTIPLEUSE);
      if (FAILED(hRes))
      {
            m_bATLInited = FALSE;
            CoUninitialize();
            return FALSE;
      }      

      return TRUE;

}

0
 

Author Comment

by:lblinc
ID: 18749768
jkr:   DllRegisterServer in C:/temp4/GBQuotesCln\Debug\GBQuotesCln.dll succeeded !!

Thanks to your help.    Now i will try and reference it from a .Net 2003 project..
0
 
LVL 86

Expert Comment

by:jkr
ID: 18749783
Yes, that's what you posted earlier. Just add the code snippet from http:Q_22457246.html#a18749634 to the above.
0
 

Author Comment

by:lblinc
ID: 18749801
No.  My bad..    Spoke too soon..   I successfully reg'd the new ATL Wizard template DLL..   not the one that i wanted.

The DLL that I created for my project gets an assertion error..   Debug Assertion Failed!

Expresion:  pM->m_hInst != 0
0
 

Author Comment

by:lblinc
ID: 18749872
After adding suggested functions..   it got  0 errors, 8 warnings...  



Deleting intermediate files and output files for project 'GBQuotesCln - Win32 Debug'.
--------------------Configuration: GBQuotesCln - Win32 Debug--------------------
Compiling resources...
Compiling...
StdAfx.cpp
Compiling...
EventHandler.cpp
GBQuotesCln.cpp
C:\satish_cpp_VC++_original\GBQuotesCln.cpp(122) : warning C4518: '__declspec(dllexport ) ' : storage-class or type specifier(s) unexpected here; ignored
C:\satish_cpp_VC++_original\GBQuotesCln.cpp(122) : warning C4502: 'linkage specification' requires use of keyword 'extern' and must precede all other specifiers
C:\satish_cpp_VC++_original\GBQuotesCln.cpp(131) : warning C4518: '__declspec(dllexport ) ' : storage-class or type specifier(s) unexpected here; ignored
C:\satish_cpp_VC++_original\GBQuotesCln.cpp(131) : warning C4502: 'linkage specification' requires use of keyword 'extern' and must precede all other specifiers
C:\satish_cpp_VC++_original\GBQuotesCln.cpp(140) : warning C4518: '__declspec(dllexport ) ' : storage-class or type specifier(s) unexpected here; ignored
C:\satish_cpp_VC++_original\GBQuotesCln.cpp(140) : warning C4502: 'linkage specification' requires use of keyword 'extern' and must precede all other specifiers
C:\satish_cpp_VC++_original\GBQuotesCln.cpp(150) : warning C4518: '__declspec(dllexport ) ' : storage-class or type specifier(s) unexpected here; ignored
C:\satish_cpp_VC++_original\GBQuotesCln.cpp(150) : warning C4502: 'linkage specification' requires use of keyword 'extern' and must precede all other specifiers
GBQuotesClnDlg.cpp
StkDlg.cpp
SymbolProcessor.cpp
Generating Code...
Linking...
   Creating library Debug/GBQuotesCln.lib and object Debug/GBQuotesCln.exp

GBQuotesCln.dll - 0 error(s), 8 warning(s)
0
 
LVL 86

Expert Comment

by:jkr
ID: 18749913
Where exactly (file, line) does that happen?
0
 

Author Comment

by:lblinc
ID: 18749928
And, i still get an assertion.    Debug Assetion Failed!    

Program:   regsvr32.exe File:  c\:Program Files\Microsoft Visual Studio\vc98\atl\include\altbase.h
Line:  5807

Expression:  pM->m_hInst != 0

then when i click 'Ignore'  i get another on next line....   5808

Expression:  pM->m_pObjMap != 0

then  DllRegisterServer in  C:/..  etc..   failed.  

Return Code was:  0xc0000005
0
 

Author Comment

by:lblinc
ID: 18749945
Here you go..  I posted all the code for my main project .cpp files below, including the functions we added per your suggestion...


// GBQuotesCln.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "GBQuotesCln.h"
#include "GBQuotesClnDlg.h"
#include <initguid.h>

#include "Eventhandler.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


/////////////////////////////////////////////////////////////////////////////
// CGBQuotesClnApp

BEGIN_MESSAGE_MAP(CGBQuotesClnApp, CWinApp)
      //{{AFX_MSG_MAP(CGBQuotesClnApp)
            // NOTE - the ClassWizard will add and remove mapping macros here.
            //    DO NOT EDIT what you see in these blocks of generated code!
      //}}AFX_MSG
      ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGBQuotesClnApp construction

CGBQuotesClnApp::CGBQuotesClnApp()
{
      // TODO: add construction code here,
      // Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CGBQuotesClnApp object

CGBQuotesClnApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CGBQuotesClnApp initialization

BOOL CGBQuotesClnApp::InitInstance()
{
      

      if (!InitATL())
            return FALSE;

      AfxEnableControlContainer();

      CCommandLineInfo cmdInfo;
      ParseCommandLine(cmdInfo);

      if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated)
      {
            return TRUE;
      }



      if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated)
      {
            return TRUE;
      }



      HRESULT hr=CoInitialize(NULL);

      if(FAILED(hr))
            AfxMessageBox("Com library not initialised!");

      // Standard initialization
      // If you are not using these features and wish to reduce the size
      //  of your final executable, you should remove from the following
      //  the specific initialization routines you do not need.

#ifdef _AFXDLL
      Enable3dControls();                  // Call this when using MFC in a shared DLL
#else
      Enable3dControlsStatic();      // Call this when linking to MFC statically
#endif

      CGBQuotesClnDlg dlg;
      m_pMainWnd = &dlg;
      int nResponse = dlg.DoModal();
      if (nResponse == IDOK)
      {
            // TODO: Place code here to handle when the dialog is
            //  dismissed with OK
      }
      else if (nResponse == IDCANCEL)
      {
            // TODO: Place code here to handle when the dialog is
            //  dismissed with Cancel
      }

      // Since the dialog has been closed, return FALSE so that we exit the
      //  application, rather than start the application's message pump.
      return FALSE;
}

      

      
CGBQuotesClnModule _Module;

BEGIN_OBJECT_MAP(ObjectMap)
END_OBJECT_MAP()




/////////////////////////////////////////////////////////////////////////////
// Used to determine whether the DLL can be unloaded by OLE

extern "C" __declspec(dllexport)
STDAPI DllCanUnloadNow(void)
{
    return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
}

/////////////////////////////////////////////////////////////////////////////
// Returns a class factory to create an object of the requested type

extern "C" __declspec(dllexport)
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
    return _Module.GetClassObject(rclsid, riid, ppv);
}

/////////////////////////////////////////////////////////////////////////////
// DllRegisterServer - Adds entries to the system registry

extern "C" __declspec(dllexport)
STDAPI DllRegisterServer(void)
{
    // registers object, typelib and all interfaces in typelib
    return _Module.RegisterServer(TRUE);
}

/////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registry

extern "C" __declspec(dllexport)
STDAPI DllUnregisterServer(void)
{
    return _Module.UnregisterServer(TRUE);
}





LONG CGBQuotesClnModule::Unlock()
{
      AfxOleUnlockApp();
      return 0;
}

LONG CGBQuotesClnModule::Lock()
{
      AfxOleLockApp();
      return 1;
}
LPCTSTR CGBQuotesClnModule::FindOneOf(LPCTSTR p1, LPCTSTR p2)
{
      while (*p1 != NULL)
      {
            LPCTSTR p = p2;
            while (*p != NULL)
            {
                  if (*p1 == *p)
                        return CharNext(p1);
                  p = CharNext(p);
            }
            p1++;
      }
      return NULL;
}


int CGBQuotesClnApp::ExitInstance()
{
      if (m_bATLInited)
      {
            _Module.RevokeClassObjects();
            _Module.Term();
            CoUninitialize();
      }

      return CWinApp::ExitInstance();

}


BOOL CGBQuotesClnApp::InitATL()
{
      m_bATLInited = TRUE;

#if _WIN32_WINNT >= 0x0400
      HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
#else
      HRESULT hRes = CoInitialize(NULL);
#endif

      if (FAILED(hRes))
      {
            m_bATLInited = FALSE;
            return FALSE;
      }

      _Module.Init(ObjectMap, AfxGetInstanceHandle());
      _Module.dwThreadID = GetCurrentThreadId();

      LPTSTR lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT
      TCHAR szTokens[] = _T("-/");

      BOOL bRun = TRUE;
      LPCTSTR lpszToken = _Module.FindOneOf(lpCmdLine, szTokens);
      while (lpszToken != NULL)
      {
            if (lstrcmpi(lpszToken, _T("UnregServer"))==0)
            {
                  _Module.UpdateRegistryFromResource(IDR_GBQUOTESCLN1, FALSE);
                  _Module.UnregisterServer(TRUE); //TRUE means typelib is unreg'd
                  bRun = FALSE;
                  break;
            }
            if (lstrcmpi(lpszToken, _T("RegServer"))==0)
            {
                  _Module.UpdateRegistryFromResource(IDR_GBQUOTESCLN1, TRUE);
                  _Module.RegisterServer(TRUE);
                  bRun = FALSE;
                  break;
            }
            lpszToken = _Module.FindOneOf(lpszToken, szTokens);
      }

      if (!bRun)
      {
            m_bATLInited = FALSE;
            _Module.Term();
            CoUninitialize();
            return FALSE;
      }

      hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
            REGCLS_MULTIPLEUSE);
      if (FAILED(hRes))
      {
            m_bATLInited = FALSE;
            CoUninitialize();
            return FALSE;
      }      

      return TRUE;

}





0
 

Author Comment

by:lblinc
ID: 18749974
The above is everything that we've been discussing thus far from the file..   GBQuotesCln.cpp

Here is the header..  not sure if that helps any ...

// GBQuotesCln.h : main header file for the GBQUOTESCLN application
//

#if !defined(AFX_GBQUOTESCLN_H__3370C76C_1F4B_43C4_B3C8_8AD0C0753953__INCLUDED_)
#define AFX_GBQUOTESCLN_H__3370C76C_1F4B_43C4_B3C8_8AD0C0753953__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef __AFXWIN_H__
      #error include 'stdafx.h' before including this file for PCH
#endif

#include "resource.h"            // main symbols


/////////////////////////////////////////////////////////////////////////////
// CGBQuotesClnApp:
// See GBQuotesCln.cpp for the implementation of this class
//

class CGBQuotesClnApp : public CWinApp
{
public:
      CGBQuotesClnApp();

// Overrides
      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CGBQuotesClnApp)
      public:
      virtual BOOL InitInstance();
            
            virtual int ExitInstance();
      //}}AFX_VIRTUAL

// Implementation

      //{{AFX_MSG(CGBQuotesClnApp)
            // NOTE - the ClassWizard will add and remove member functions here.
            //    DO NOT EDIT what you see in these blocks of generated code !
      //}}AFX_MSG
      DECLARE_MESSAGE_MAP()
private:
      
private:
      BOOL m_bATLInited;
      BOOL InitATL();
      
};


/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_GBQUOTESCLN_H__3370C76C_1F4B_43C4_B3C8_8AD0C0753953__INCLUDED_)


0
 
LVL 86

Expert Comment

by:jkr
ID: 18750073
Ah, think I got it - we'll need a 'DllMain()' for the module initialization stuff:


void InitATL()
{
#if _WIN32_WINNT >= 0x0400
      HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
#else
      HRESULT hRes = CoInitialize(NULL);
#endif

      _Module.Init(ObjectMap, AfxGetInstanceHandle());
      _Module.dwThreadID = GetCurrentThreadId();
}

BOOL WINAPI DllMain(
  HINSTANCE hinstDLL,  // handle to DLL module
  DWORD fdwReason,     // reason for calling function
  LPVOID lpvReserved   // reserved
)
{
  if(fdwReason == DLL_PROCESS_ATTACH) InitATL();

  return TRUE;
}

0
 

Author Comment

by:lblinc
ID: 18750215
jkr:     I'm afraid my knowledge of C++ is just not where it needs to be to do any meaningful debugging here in any reasonable timeframe.     I've been working with C# for the last 2 years...

I seem to get things to compile ok without any problems..  but then the DLL cannot be registered.

I don't know if you want to take a look at the entire project..  15 files total..  actually not that big.   Very clean C++  code..

If so, I could zip up the files and send them to you..    I'm at a loss..  
0
 

Author Comment

by:lblinc
ID: 18750260
For whatever reason,  it doesn't like these lines starting with the STDAPI -->

STDAPI DllCanUnloadNow(void)
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
STDAPI DllRegisterServer(void)
STDAPI DllUnregisterServer(void)

this is the output....


Deleting intermediate files and output files for project 'GBQuotesCln - Win32 Debug'.
--------------------Configuration: GBQuotesCln - Win32 Debug--------------------
Compiling resources...
Compiling...
StdAfx.cpp
Compiling...
EventHandler.cpp
GBQuotesCln.cpp
C:\satish_cpp_VC++_original\GBQuotesCln.cpp(145) : warning C4518: '__declspec(dllexport ) ' : storage-class or type specifier(s) unexpected here; ignored
C:\satish_cpp_VC++_original\GBQuotesCln.cpp(145) : warning C4502: 'linkage specification' requires use of keyword 'extern' and must precede all other specifiers
C:\satish_cpp_VC++_original\GBQuotesCln.cpp(154) : warning C4518: '__declspec(dllexport ) ' : storage-class or type specifier(s) unexpected here; ignored
C:\satish_cpp_VC++_original\GBQuotesCln.cpp(154) : warning C4502: 'linkage specification' requires use of keyword 'extern' and must precede all other specifiers
C:\satish_cpp_VC++_original\GBQuotesCln.cpp(163) : warning C4518: '__declspec(dllexport ) ' : storage-class or type specifier(s) unexpected here; ignored
C:\satish_cpp_VC++_original\GBQuotesCln.cpp(163) : warning C4502: 'linkage specification' requires use of keyword 'extern' and must precede all other specifiers
C:\satish_cpp_VC++_original\GBQuotesCln.cpp(173) : warning C4518: '__declspec(dllexport ) ' : storage-class or type specifier(s) unexpected here; ignored
C:\satish_cpp_VC++_original\GBQuotesCln.cpp(173) : warning C4502: 'linkage specification' requires use of keyword 'extern' and must precede all other specifiers
GBQuotesClnDlg.cpp
StkDlg.cpp
SymbolProcessor.cpp
Generating Code...
Linking...
   Creating library Debug/GBQuotesCln.lib and object Debug/GBQuotesCln.exp

GBQuotesCln.dll - 0 error(s), 8 warning(s)

0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 100 total points
ID: 18750359
After reading the thread I wonder whether it is not much easier to create a new dll by using the VC 6.0 ATL wizard and then add the code from the two cpp files. The wizard generated code most likely overcomes most difficulties you experienced when changing the options manually.

Note, you most likely can generate wizard code for all functions you want to overtake from the existing sources. That way you only need to add the pure implementations.

Regards, Alex
0
 
LVL 86

Expert Comment

by:jkr
ID: 18750370
You still get the assertion after adding the 'DllMain()' code?
0
 

Author Comment

by:lblinc
ID: 18750371
It seems to compile smoothly without the      __declspec(dllexport)       but i still get assertions..

regsvr32.exe  afxwin1.ini    Line 19
regsvr32.exe  altbase.h    Line 5807   Expression:  pM->m_hInst != 0



i was trying the following...


void InitATL()
{
#if _WIN32_WINNT >= 0x0400
      HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
#else
      HRESULT hRes = CoInitialize(NULL);
#endif

      _Module.Init(ObjectMap, AfxGetInstanceHandle());
      _Module.dwThreadID = GetCurrentThreadId();
}

extern "C"
BOOL WINAPI DllMain(
  HINSTANCE hinstDLL,  // handle to DLL module
  DWORD fdwReason,     // reason for calling function
  LPVOID lpvReserved   // reserved
)
{
  if(fdwReason == DLL_PROCESS_ATTACH) InitATL();

  return TRUE;
}


/////////////////////////////////////////////////////////////////////////////
// Used to determine whether the DLL can be unloaded by OLE

extern "C"
STDAPI DllCanUnloadNow(void)
{
    return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
}

/////////////////////////////////////////////////////////////////////////////
// Returns a class factory to create an object of the requested type

extern "C"
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
    return _Module.GetClassObject(rclsid, riid, ppv);
}

/////////////////////////////////////////////////////////////////////////////
// DllRegisterServer - Adds entries to the system registry

extern "C"
STDAPI DllRegisterServer(void)
{
    // registers object, typelib and all interfaces in typelib
    return _Module.RegisterServer(TRUE);
}

/////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registry

extern "C"
STDAPI DllUnregisterServer(void)
{
    return _Module.UnregisterServer(TRUE);
}
0
 

Author Comment

by:lblinc
ID: 18750466
itsmeandnobodyelse  ~    I will try that and get back, although i was tryign that route at the start but still having complications.

Give me an hour or so to try again, as I can try some of these tips from jkr above this time around.

Appreciate the input.
0
 
LVL 86

Expert Comment

by:jkr
ID: 18750747
If you have added the .def file, you won't need the '__declspec()' stuff, that's right. Apart from that, you were just seeing warnings. Anyway, are you still gettin gthe assertion?
0
 

Author Comment

by:lblinc
ID: 18751455
jkr:   When creating test DLL using the ATL Wizard ..    this file  Test_i.c t is generated?     This file contains the actual definitions of IIDs and CLSIDs..    maybe that is the reason?

As follows:

/* this file contains the actual definitions of */
/* the IIDs and CLSIDs */

/* link this file in with the server and any clients */


/* File created by MIDL compiler version 5.01.0164 */
/* at Mon Mar 19 16:28:14 2007
 */
/* Compiler settings for C:\temp4\Test\Test.idl:
    Oicf (OptLev=i2), W1, Zp8, env=Win32, ms_ext, c_ext
    error checks: allocation ref bounds_check enum stub_data
*/
//@@MIDL_FILE_HEADING(  )
#ifdef __cplusplus
extern "C"{
#endif


#ifndef __IID_DEFINED__
#define __IID_DEFINED__

typedef struct _IID
{
    unsigned long x;
    unsigned short s1;
    unsigned short s2;
    unsigned char  c[8];
} IID;

#endif // __IID_DEFINED__

#ifndef CLSID_DEFINED
#define CLSID_DEFINED
typedef IID CLSID;
#endif // CLSID_DEFINED

const IID LIBID_TESTLib = {0xE0429118,0xE9CF,0x41AA,{0x8E,0x4B,0x55,0xCA,0x8B,0xBD,0x54,0x42}};


#ifdef __cplusplus
}
#endif

0
 

Author Comment

by:lblinc
ID: 18751458
Then it would be used as follows in the Test.cpp   ...


// Note: Proxy/Stub Information
//      To build a separate proxy/stub DLL,
//      run nmake -f Testps.mk in the project directory.

#include "stdafx.h"
#include "resource.h"
#include <initguid.h>
#include "Test.h"

#include "Test_i.c"


CComModule _Module;

BEGIN_OBJECT_MAP(ObjectMap)
END_OBJECT_MAP()

/////////////////////////////////////////////////////////////////////////////
// DLL Entry Point

extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        _Module.Init(ObjectMap, hInstance, &LIBID_TESTLib);
        DisableThreadLibraryCalls(hInstance);
    }
    else if (dwReason == DLL_PROCESS_DETACH)
        _Module.Term();
    return TRUE;    // ok
}

/////////////////////////////////////////////////////////////////////////////
// Used to determine whether the DLL can be unloaded by OLE

STDAPI DllCanUnloadNow(void)
{
    return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
}

/////////////////////////////////////////////////////////////////////////////
// Returns a class factory to create an object of the requested type

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
    return _Module.GetClassObject(rclsid, riid, ppv);
}

/////////////////////////////////////////////////////////////////////////////
// DllRegisterServer - Adds entries to the system registry

STDAPI DllRegisterServer(void)
{
    // registers object, typelib and all interfaces in typelib
    return _Module.RegisterServer(TRUE);
}

/////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registry

STDAPI DllUnregisterServer(void)
{
    return _Module.UnregisterServer(TRUE);
}


0
 

Author Comment

by:lblinc
ID: 18751477
Test_i.c   looks like it defines extern "C"   and sets the IID  for the   LPVOID /*lpReserved*/   arg  in the  DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
0
 
LVL 86

Expert Comment

by:jkr
ID: 18751524
The generated stub code is for function call data marshaling - you should find similar files in your old project, this is quite unlikely the reason for the assertion.
0
 

Author Comment

by:lblinc
ID: 18752441
jkr  ~  I'm still at the place where the project compiles fine....

Deleting intermediate files and output files for project 'GBQuotesCln - Win32 Debug'.
--------------------Configuration: GBQuotesCln - Win32 Debug--------------------
Compiling resources...
Compiling...
StdAfx.cpp
Compiling...
EventHandler.cpp
GBQuotesCln.cpp
GBQuotesClnDlg.cpp
StkDlg.cpp
SymbolProcessor.cpp
Generating Code...
Linking...
Creating browse info file...

GBQuotesCln.dll - 0 error(s), 0 warning(s)

BUT, the DLL will not reg...

First Message:

Debug Assertion Failed!  
regsvr32.exe afxwin1.inl
Line:  19
(Press Retry to Debug the Application)

When I press 'Retry' ...
LoadLibrary(C\:...\...\GBQuotesCln.dll" failed -  One or more arguments are invalid.

0
 

Author Comment

by:lblinc
ID: 18752457
Here's my latest code from GBQuotesCln.cpp  ...

// GBQuotesCln.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "GBQuotesCln.h"
#include "GBQuotesClnDlg.h"
#include <initguid.h>

#include "Eventhandler.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CGBQuotesClnApp

BEGIN_MESSAGE_MAP(CGBQuotesClnApp, CWinApp)
      //{{AFX_MSG_MAP(CGBQuotesClnApp)
            // NOTE - the ClassWizard will add and remove mapping macros here.
            //    DO NOT EDIT what you see in these blocks of generated code!
      //}}AFX_MSG
      ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGBQuotesClnApp construction

CGBQuotesClnApp::CGBQuotesClnApp()
{
      // TODO: add construction code here,
      // Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CGBQuotesClnApp object

CGBQuotesClnApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CGBQuotesClnApp initialization

BOOL CGBQuotesClnApp::InitInstance()
{
      

      if (!InitATL())
            return FALSE;

      AfxEnableControlContainer();

      CCommandLineInfo cmdInfo;
      ParseCommandLine(cmdInfo);

      if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated)
      {
            return TRUE;
      }



      if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated)
      {
            return TRUE;
      }



      HRESULT hr=CoInitialize(NULL);

      if(FAILED(hr))
            AfxMessageBox("Com library not initialised!");

      // Standard initialization
      // If you are not using these features and wish to reduce the size
      //  of your final executable, you should remove from the following
      //  the specific initialization routines you do not need.

#ifdef _AFXDLL
      Enable3dControls();                  // Call this when using MFC in a shared DLL
#else
      Enable3dControlsStatic();      // Call this when linking to MFC statically
#endif

      CGBQuotesClnDlg dlg;
      m_pMainWnd = &dlg;
      int nResponse = dlg.DoModal();
      if (nResponse == IDOK)
      {
            // TODO: Place code here to handle when the dialog is
            //  dismissed with OK
      }
      else if (nResponse == IDCANCEL)
      {
            // TODO: Place code here to handle when the dialog is
            //  dismissed with Cancel
      }

      // Since the dialog has been closed, return FALSE so that we exit the
      //  application, rather than start the application's message pump.
      return FALSE;
}

      

      
CGBQuotesClnModule _Module;

BEGIN_OBJECT_MAP(ObjectMap)
END_OBJECT_MAP()

LONG CGBQuotesClnModule::Unlock()
{
      AfxOleUnlockApp();
      return 0;
}

LONG CGBQuotesClnModule::Lock()
{
      AfxOleLockApp();
      return 1;
}
LPCTSTR CGBQuotesClnModule::FindOneOf(LPCTSTR p1, LPCTSTR p2)
{
      while (*p1 != NULL)
      {
            LPCTSTR p = p2;
            while (*p != NULL)
            {
                  if (*p1 == *p)
                        return CharNext(p1);
                  p = CharNext(p);
            }
            p1++;
      }
      return NULL;
}


int CGBQuotesClnApp::ExitInstance()
{
      if (m_bATLInited)
      {
            _Module.RevokeClassObjects();
            _Module.Term();
            CoUninitialize();
      }

      return CWinApp::ExitInstance();

}

BOOL CGBQuotesClnApp::InitATL()
{
      m_bATLInited = TRUE;

#if _WIN32_WINNT >= 0x0400
      HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
#else
      HRESULT hRes = CoInitialize(NULL);
#endif

      if (FAILED(hRes))
      {
            m_bATLInited = FALSE;
            return FALSE;
      }

      _Module.Init(ObjectMap, AfxGetInstanceHandle());
      _Module.dwThreadID = GetCurrentThreadId();

      LPTSTR lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT
      TCHAR szTokens[] = _T("-/");

      BOOL bRun = TRUE;
      LPCTSTR lpszToken = _Module.FindOneOf(lpCmdLine, szTokens);
      while (lpszToken != NULL)
      {
            if (lstrcmpi(lpszToken, _T("UnregServer"))==0)
            {
                  _Module.UpdateRegistryFromResource(IDR_GBQUOTESCLN1, FALSE);
                  _Module.UnregisterServer(TRUE); //TRUE means typelib is unreg'd
                  bRun = FALSE;
                  break;
            }
            if (lstrcmpi(lpszToken, _T("RegServer"))==0)
            {
                  _Module.UpdateRegistryFromResource(IDR_GBQUOTESCLN1, TRUE);
                  _Module.RegisterServer(TRUE);
                  bRun = FALSE;
                  break;
            }
            lpszToken = _Module.FindOneOf(lpszToken, szTokens);
      }

      if (!bRun)
      {
            m_bATLInited = FALSE;
            _Module.Term();
            CoUninitialize();
            return FALSE;
      }

      hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
            REGCLS_MULTIPLEUSE);
      if (FAILED(hRes))
      {
            m_bATLInited = FALSE;
            CoUninitialize();
            return FALSE;
      }      

      return TRUE;
}

void InitATL()
{
#if _WIN32_WINNT >= 0x0400
      HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
#else
      HRESULT hRes = CoInitialize(NULL);
#endif

      _Module.Init(ObjectMap, AfxGetInstanceHandle());
      _Module.dwThreadID = GetCurrentThreadId();
}



/////////////////////////////////////////////////////////////////////////////
// DLL Entry Point

extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
    if (dwReason == DLL_PROCESS_ATTACH)
    {
            InitATL();
        //_Module.Init(ObjectMap, hInstance, &LIBID_GBQUOTESCLNLib);
        DisableThreadLibraryCalls(hInstance);
    }
    else if (dwReason == DLL_PROCESS_DETACH)
        _Module.Term();
    return TRUE;    // ok
}

/////////////////////////////////////////////////////////////////////////////
// Used to determine whether the DLL can be unloaded by OLE

STDAPI DllCanUnloadNow(void)
{
    return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
}

/////////////////////////////////////////////////////////////////////////////
// Returns a class factory to create an object of the requested type

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
    return _Module.GetClassObject(rclsid, riid, ppv);
}

/////////////////////////////////////////////////////////////////////////////
// DllRegisterServer - Adds entries to the system registry

STDAPI DllRegisterServer(void)
{
    // registers object, typelib and all interfaces in typelib
    return _Module.RegisterServer(TRUE);
}

/////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registry

STDAPI DllUnregisterServer(void)
{
    return _Module.UnregisterServer(TRUE);
}

0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now