【问题标题】:Use .NET in an C++/MFC applications?在 C++/MFC 应用程序中使用 .NET?
【发布时间】:2013-03-23 11:42:29
【问题描述】:

我们管理和开发的程序是用 C++/MFC 编写的。我们希望将其现代化为 .NET,但不想立即重写整个应用程序。因此,我们正在考虑用 .NET 编写程序的新部分,同时用 C++/MFC 维护程序的其余部分。

当我们在 Internet 上读到这一点时,它说了很多关于从托管代码调用非托管代码的内容。但我们想以另一种方式来做。我们查到了一些资料表明是可以的,但是看起来非常繁琐和繁琐。

这可能吗? 这是一个很好的解决方案吗? 有没有更好的方法来逐步使程序现代化?

【问题讨论】:

  • 你是说组件?还有你想用 C# 写什么样的代码,例如:业务逻辑、UI?
  • 我们还是想用C++程序做的改动不是以组件的形式,而是代码中到处都有细微的改动
  • 所以我的朋友,我认为对你来说最好的选择,恰好也是最简单的选择是使用 COM+。您可以保持您的 C++ 代码库不变,而不必担心用于 c++->C# 绑定的第三方库,同时拥有像 C# 代码库这样的合约,一旦您准备好完全迁移到 .NET,就可以轻松使用它。

标签: .net mfc c++-cli


【解决方案1】:

最简单的存档方法是使用 COM+ 托管您的 C#,然后从 C++ 添加这些 COM+ 作为引用。这是一个简单的过程,还增加了一些好处,例如代码封装。

http://my.execpc.com/~gopalan/dotnet/complus/complus.net_accountmanager.html

【讨论】:

  • 所以不能在同一个代码库中混合原生C++和C++/CLI?
  • 我不知道是否可能,很可能有人编写了一个提供该功能的库,但即使这是一种方式,我也建议您不要这样做。构建您的 C# 组件,将它们部署为 COM¨+ 组件。构建一个调用这些 COM+ 组件的 C++ 库,它可以有效地从现有代码库中隐藏该逻辑,从而帮助您保持代码整洁,并将该库用作系统的外部提供程序。这是我的建议。
【解决方案2】:

使用 C++/CLI 来使用 C++/MFC 代码中的 .NET 部分是一种常用方法。当你了解它时,它并不难。 .NET UI 控件应该有一个方法来设置父窗口的 HWND 和控件的大小(虽然不是所有的都有)。许多 .NET 组件苦苦挣扎的另一件事是 .NET 程序集的混淆,这会阻止使用 C++/CLI 中的控件。

我们是一家 .net 图表制造商,客户已使用我们的产品对其应用进行现代化改造。我们有关于如何从 C++/CLI 使用 .NET 图表的文档和示例应用程序。

#using "Arction.LightningChartUltimate.dll"
using namespace Arction::LightningChartUltimate;

//"Global managed variables"  
ref class GlobalObjects {
public:
   static Arction::LightningChartUltimate::LightningChartUltimate^ chart; 
}; 

void CMainFrame::CreateChart(HWND hwndParent)
{

    GlobalObjects^ go = gcnew GlobalObjects();

    //Embeddable trial key is used here. 
    go->chart = gcnew LightningChartUltimate("licensekey"); 

    LightningChartUltimate^ chart = go->chart;

    //Disable repaints for every property change
    chart->BeginUpdate(); 

    //Set parent window by window handle
    chart->SetParentWindow((System::IntPtr) hwndParent); 

    //Remove existing series 
    chart->ViewXY->PointLineSeries->Clear(); 

    //Create new series 
    PointLineSeries^ series = gcnew PointLineSeries(chart->ViewXY, chart->ViewXY->XAxes[0], chart->ViewXY->YAxes[0]);
    const int PointCount = 10; 

    //Create SeriesPoint array
    array<SeriesPoint> ^ data =
        gcnew array<SeriesPoint>(PointCount);

    //Fill the array
    double yValues[PointCount] = {0.0, 5.0, 4.0, 3.0, 8.0, 10.0, 9.0, 8.0, 3.0, 2.0};
    for(int i=0; i<PointCount; i++)
    {
        data[i].X = i+1; 
        data[i].Y = yValues[i]; 
    }

    //Add the points to series
    series->AddPoints(data,false);

    //Add the series itself into chart's PointLineSeries collection
    chart->ViewXY->PointLineSeries->Add(series); 

    //Fit the axis ranges to data assigned
    chart->ViewXY->FitView();

    //Allow repaints, update chart
    chart->EndUpdate();  

} 

void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
    __super::OnSize(nType, cx, cy);

    RECT rectStatusBar;
    if (m_wndStatusBar.m_hWnd)
        m_wndStatusBar.GetClientRect(&rectStatusBar);

    //Set the new size to LightningChart object, with SetBounds method call
    GlobalObjects^ go = gcnew GlobalObjects();
    if (go)
    {
        LightningChartUltimate^ chart = go->chart;
        if (chart)
            chart->SetBounds(2, 2, cx - 4, cy - rectStatusBar.bottom - 2);
    }
}

并不比这更难,所需的代码量几乎与 C# 相同。

另一种方法是使用 C#(WinForms 或 WPF)创建新的 DLL,并为 C++ 应用程序导出一个简单的 API,从而最大限度地减少非托管端的 C++/CLI 使用。

(我是 LightningChart 组件的 CTO。)

【讨论】:

    猜你喜欢
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 2016-04-23
    • 1970-01-01
    • 2012-11-22
    • 2018-08-27
    相关资源
    最近更新 更多