可以使用C ++ / CLI从本机C ++应用程序调用.NET代码吗?

时间:2009-06-29 15:21:21

标签: .net c++ interop c++-cli

我已经用C ++ / CLI完成了另一种方式(从.NET调用纯C ++代码),并且它(大多数情况下)都有用。

如何完成本机到C ++ / CLI的指导?

我真的不想使用COM互操作......

5 个答案:

答案 0 :(得分:22)

如果你有一个现有的原生C ++应用程序,并希望避免使用过多的CLR东西“污染”它,你可以只为一个特定文件打开/clr标志,并使用标准C ++标头来提供它的接口。我用一些旧的代码完成了这个。在标题中我有:

void SaveIconAsPng(void *hIcon, const wchar_t *pstrFileName);

所以程序的其余部分有一个简单的API,它可以传递HICON和目标文件路径。

然后我有一个单独的源文件,这是唯一一个/clr开启的文件:

using namespace System;
using namespace System::Drawing;
using namespace System::Drawing::Imaging;
using namespace System::Drawing::Drawing2D;

#include <vcclr.h> 
#include <wchar.h>

void SaveIconAsPng(void *hIcon, const wchar_t *pstrFileName)
{
    try
    {
        Bitmap bitmap(16, 16, PixelFormat::Format32bppArgb);

        Graphics ^graphics = Graphics::FromImage(%bitmap);
        graphics->SmoothingMode = SmoothingMode::None;

        Icon ^icon = Icon::FromHandle(IntPtr(hIcon));
        graphics->DrawIcon(icon, Rectangle(0, 0, 15, 15));
        graphics->Flush();

        bitmap.Save(gcnew String(pstrFileName), ImageFormat::Png);
    }
    catch (Exception ^x)
    {
        pin_ptr<const wchar_t> unmngStr = PtrToStringChars(x->Message);
        throw widestring_error(unmngStr); // custom exception type based on std::exception
    }
}

这样我可以将HICON转换成我多毛的旧C ++程序中的PNG文件,但我已经从其余的代码中分离出.NET框架的使用 - 所以如果我以后需要移植,我可以很容易交换不同的实现。

你可以进一步将这一点放在一个单独的DLL中,并将CLR相关的代码放在一个单独的DLL中,尽管除非你想单独修补它,否则几乎没有附加价值。

答案 1 :(得分:5)

您可以随时在本机应用中使用host the CLR

答案 2 :(得分:3)

本书C++/CLI in Action有一个名为Mixing Managed and Native Code的章节,在本章的内容下,在Working With Interop Mechanisms标题下,它讨论了从本机代码访问托管库和从托管代码访问本机库的问题。 。当我每次阅读它时,它确实帮助我理解了这些概念。

答案 3 :(得分:1)

你应该看看Unmanaged Exports,你可以NuGet package获得。这是根据作者的描述:

  

一组编译时库(无需部署)和一个构建任务,使您可以将函数从托管代码导出到本机应用程序。这意味着,您可以使用C#或F#等托管语言为仅具有C-Api(如Notepad ++)的本机应用程序创建插件。 nuget包就是您所需要的。只需使用[DllExport]标记您的方法,然后为x86,x64或ia64构建。

答案 4 :(得分:-2)

从C ++ / CLI调用.NET代码非常简单。它与常规C ++非常相似。确保您的项目设置为C ++ / CLI项目,通过转到“公共属性”下的项目属性添加对.NET程序集的引用,然后将.NET对象与以下代码一起使用:

using namespace System;
using namespace System::Collections::Generic;
using namespace MyNamespace;

void MyFunctionCall()
{
  MyObject ^obj = gcnew MyObject();
  obj->MyMethod();

  // ...
}