none
how to call managed c++ from unmanaged c++ ? RRS feed

  • Question

  • Hi,

    Anybody knows how to expose an interface from unmanaged MFC C++ to managed c++ within the same application ?
    I have a managed c++ class and an unmanaged MFC c++ class, and am trying to create an object of managed class with keeping the application's compile option as unmanaged.

    jsk
    Thursday, September 18, 2008 1:39 AM

Answers

  • Use the hosting api to host the runtime in your application.  Here is an example I found on codeproject. 


    http://www.codeproject.com/KB/COM/simpleclrhost.aspx
    http://www.codeproject.com/KB/dotnet/HostCLRwithoutDotNet.aspx

        CComPtr<ICorRuntimeHost>    spRuntimeHost;
        CComPtr<_AppDomain>            spDefAppDomain;
       
        //Retrieve a pointer to the ICorRuntimeHost interface
        HRESULT hr = CorBindToRuntimeEx(
                                                 NULL,    //Retrieve latest version by default
                                                 L"wks",    //Request a WorkStation build of the CLR
                                                 STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN | STARTUP_CONCURRENT_GC,
                                                 CLSID_CorRuntimeHost,
                                                 IID_ICorRuntimeHost,
                                                 (void**)&spRuntimeHost
                                                 );

        if (FAILED(hr)) return hr;

        //Start the CLR
        hr = spRuntimeHost->Start();

        CComPtr<IUnknown> pUnk;
        //Retrieve the IUnknown default AppDomain
        hr = spRuntimeHost->GetDefaultDomain(&pUnk);
        if (FAILED(hr)) return hr;

        hr = pUnk->QueryInterface(&spDefAppDomain.p);
        if (FAILED(hr)) return hr;

        CComPtr<_ObjectHandle> spObjectHandle;

        //Creates an instance of the type specified in the Assembly
        hr = spDefAppDomain->CreateInstance(
                                                        _bstr_t("HelloMsgBox"),
                                                        _bstr_t("Ranjeet.SimpleCLRHost.HelloHostDemo"),
                                                        &spObjectHandle
                                                        );



    • Marked as answer by Zhi-Xin Ye Wednesday, September 24, 2008 9:38 AM
    Wednesday, September 24, 2008 4:08 AM

All replies

  • Sure.  There are some extensions called CLI C++ ( used to be managed extension and had different sytax prior to vs 2005)

    You need to compile with the /clr flag.  Use pragma managed and pragma unmanaged directives to switch between managed and unmanaged code. 

    Pragma managed/unmanaged
    http://msdn.microsoft.com/en-us/library/0adb9zxe.aspx

    CLI C++
    http://msdn.microsoft.com/en-us/magazine/cc163971.aspx
    Thursday, September 18, 2008 3:05 AM
  •  Thanks for your reply.
    The thing is I can not turn on "/clr" flag for the whole application due to the compatibility issue,
    but only for the managed class I turned it on and for the rest classess it's off.
    Is there anyway to create an object of managed class in unmanaged class in this situation ?
    jsk
    Thursday, September 18, 2008 6:06 AM
  • You can maybe host the .net runtime then in your application.  I wrote a test c++ app that does this a while ago but I am on a business trip and I don't have the source on my laptop.  Maybe tomorrow NoBugz can write you an example.  I beleive it was only a couple lines of code needed but I don't remember.

    ICorRuntimehost
    http://msdn.microsoft.com/en-us/library/ms164320.aspx


    Hosting Interfaces for the .NET Framework 2.0 and Later
    http://msdn.microsoft.com/en-us/library/ms164336.aspx
    Thursday, September 18, 2008 6:42 AM
  • i think you can use #pragma managed and #pragma unmanaged as i said in the other thread (and put your code within them), but i probably have no idea what i'm talking about!
    Tuesday, September 23, 2008 8:02 PM
  • To include an interface to managed code, at least part of your application needs to be compiled with the /clr switch. Only the object files that have any managed components need this though--the rest of the object files can be compiled without it. The linker will merge this together and create a "mixed assembly" that has both managed IL and native machine code.

    Thus, the file with the ref class code need only include the header with the native class definition in order to wrap it. This is exactly what C++/CLI is designed to do.

    In fact, compiling only the parts of a C++ application that need to be managed with the /clr switch is a best practice.
    Brandon Bray, Visual C++ Compiler
    Wednesday, September 24, 2008 2:29 AM
    Moderator
  • Use the hosting api to host the runtime in your application.  Here is an example I found on codeproject. 


    http://www.codeproject.com/KB/COM/simpleclrhost.aspx
    http://www.codeproject.com/KB/dotnet/HostCLRwithoutDotNet.aspx

        CComPtr<ICorRuntimeHost>    spRuntimeHost;
        CComPtr<_AppDomain>            spDefAppDomain;
       
        //Retrieve a pointer to the ICorRuntimeHost interface
        HRESULT hr = CorBindToRuntimeEx(
                                                 NULL,    //Retrieve latest version by default
                                                 L"wks",    //Request a WorkStation build of the CLR
                                                 STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN | STARTUP_CONCURRENT_GC,
                                                 CLSID_CorRuntimeHost,
                                                 IID_ICorRuntimeHost,
                                                 (void**)&spRuntimeHost
                                                 );

        if (FAILED(hr)) return hr;

        //Start the CLR
        hr = spRuntimeHost->Start();

        CComPtr<IUnknown> pUnk;
        //Retrieve the IUnknown default AppDomain
        hr = spRuntimeHost->GetDefaultDomain(&pUnk);
        if (FAILED(hr)) return hr;

        hr = pUnk->QueryInterface(&spDefAppDomain.p);
        if (FAILED(hr)) return hr;

        CComPtr<_ObjectHandle> spObjectHandle;

        //Creates an instance of the type specified in the Assembly
        hr = spDefAppDomain->CreateInstance(
                                                        _bstr_t("HelloMsgBox"),
                                                        _bstr_t("Ranjeet.SimpleCLRHost.HelloHostDemo"),
                                                        &spObjectHandle
                                                        );



    • Marked as answer by Zhi-Xin Ye Wednesday, September 24, 2008 9:38 AM
    Wednesday, September 24, 2008 4:08 AM