English 中文(简体)
尽管C#功能在非违约情况下需要使用,但C++点子的接口
原标题:Marshalling C++ pointer interface back though C# function call in a non default AppDomain

在C++和C#代码之间,我有一个行之有效的CLI接口。 该法典有一套C++抽象的接口,例如:

-------------C++ Interface---------------
namespace cppns
{
   class cppInterface
   {
      public:
         virtual bool Start(const char *pcDir) = 0;
   };
}

------Implementation of abstract C++ interface in same dll---------
namespace cppns
{
   class cppimp : public cppInterface
   private:
       gcroot<MyInternalCSharpClass^> mInternalClassAccess;
   public:
       cppimp::cppimp()
       {
           mInternalClassAccess = gcnew MyInternalCSharpClass();
       }

       virtual bool cppimp::Start(const char *pcDir)
       {
           System::AppDomain ^appDom = AppDomain::CurrentDomain::get();
           System::String ^strDomainName = appDom->FriendlyName;

           mInternalClassAccess->Initalize(pcDir);
       }
}

---------Method to create an instance of the class in a factory--------------
cppns::cppInterface *GetImplObject()
{
    return new cppns::cppimp();
}

----------Factory class .h to allow C++ to get an instance of the cppimp class------
------The C++ code knows about the abstract interface by including the header file--
------FactoryExport is __declspec(dllexport) when compiled in dll and---------------
----- __declspec(dllimport) when used as a header file in exe that uses header------
class FactoryExport ClassFactory
{
    public:
       static cppns::cppInterface *CreateImpl();
};

----------Factory class .cpp to allow C++ to get an instance of the cppimp class------
cppns::cppInterface *ClassFactory::CreateImpl()
{
    return GetImplObject();
}

这部法律使我能够呼吁创建Impl,以实施包含启动方法的接口。 我的问题是,我试图强迫整个《刑法》生效。 NET 装入一个不是缺电的应用程序。 我可以使用以下法典设立第二位上诉人:

   CComPtr<ICorRuntimeHost> pRuntimeHost;
   //Retrieve a pointer to the ICorRuntimeHost interface
   HRESULT hr = CorBindToRuntimeEx(
                L"v2.0.50727", //Retrieve last version before 4.0.
                // NULL, //Retrieve latest version by default
                L"wks",
                STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN | STARTUP_CONCURRENT_GC, 
                CLSID_CorRuntimeHost,
                IID_ICorRuntimeHost,
                (void**)&pRuntimeHost.p
                );

hr = pRuntimeHost->Start();

DWORD dwAppDomainId = 22;
WCHAR domainName[80 + 1];
    swprintf(domainName, 80, L"%s-%ld",L"NoDefaultDomain", dwAppDomainId);

CComPtr<IUnknown> pUnknownAppDomain;
hr = pRuntimeHost->CreateDomainEx(domainName, NULL, NULL, &pUnknownAppDomain);

CComPtr<_AppDomain> pAppDomain;
hr = pUnknownAppDomain->QueryInterface(__uuidof(_AppDomain), (VOID**)&pAppDomain.p);

BSTR bstrFriendlyName;
hr = pAppDomain->get_FriendlyName(&bstrFriendlyName);
if (SUCCEEDED(hr))
{
    _bstr_t bstrFriendlyNameWrap(bstrFriendlyName, false);
}

_bstr_t bstrAssemblyName("InteropCode");
CComPtr<_Assembly> pAssembly;
hr = pAppDomain->Load_2(bstrAssemblyName, &pAssembly);

BSTR bstrFullName;
hr = pAssembly->get_FullName(&bstrFullName);
if (SUCCEEDED(hr))
{
    _bstr_t bstrFullNameWrap(bstrFullName, false);
    std::cout << "Assembly name is: " << bstrFullNameWrap << "
";
}

每一次试图让工厂回到我中间,把电梯运回,都失败了。 我甚至试图建立一个二级工厂,即C#级,把点人归到已安装的接口中,以便印度人呼吁大会,希望该法典的其余部分在上诉法院执行,我把大会装进,但因沃克人把一个身份识别器送回,我似乎无法把身份识别器重新绘制到我接口的任何类型的C++点。

namespace cppns
{
    public ref class NetFactory
    {
    public:
        NetFactory()
        {
        }

        cppInterface *CreateInterop()
        {
            return GetImplObject();;
        }
    };
}

是否有另一种途径使所有东西都能在二级上诉程序中运行,或者在称为启动方法时,国际发展法的派遣方是可行的吗?

最佳回答

I have managed to get most of the .NET stuff running in another domain. It seems like there is no way to get the CLI layer to run in anything other than the default AppDomain.

为了完成这项工作,我需要使两座 app子中坐下来的班子都来自马萨尔·雷夫奥奇。 在上述例子中,这意味着我不得不改变MyInternalCSharpClass,以便从MarsalByRefObject获得。 把从MyInternalCSharpClass送来和归还的物体也从Marsal ByRefObject中取出,也是合情合理的。 最后,这些已经通过和归还的物体必须拥有[可再生]财产,并标明其所有私人变量。 请注意,如果申请人已经使用可扩展的属性而转让这些类别,则你可以在每个正式私人变量上使用[XmlIgnore],以避免改变正在进行的序列化。

既然所有事情都可以在申请人之间转移,我就设立了第二个申请人,具体做法如下:

bool CreateInstanceInAppDomain(const char *pcAppDomainName)
{
    bool bRtn = false;

    gcroot<String^> csStrAppDomainName (gcnew String(pcAppDomainName));
    mAppDomain = AppDomain::CreateDomain(csStrAppDomainName);
    delete csStrAppDomainName;
    Object^ MyInternalObject = mAppDomain->CreateInstanceAndUnwrap("AssemblyName", "ClassNameSpace.MyInternalCSharpClass");
    mInternalClassAccess = dynamic_cast<MyInternalCSharpClass^>(MyInternalObject);
    if (mInternalClassAccess)
    {
        bRtn = true;
    }

    return bRtn;
}
问题回答

暂无回答




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签