能否使用 C++/CLI 从本机 C++ 调用 .NET 代码? 应用程序?

发布于 2024-07-25 07:06:51 字数 121 浏览 2 评论 0原文

我已经使用 C++/CLI 完成了另一种方法(从 .NET 调用纯 C++ 代码),并且它有效(大部分)。

本机到 C++/CLI 方向是如何完成的?

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

I've done the other way around (calling pure C++ code from .NET) with C++/CLI, and it worked (for the most part).

How is the native-to-C++/CLI direction done?

I really don't want to use COM interop...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

熊抱啵儿 2024-08-01 07:06:51

如果您有一个现有的本机 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 框架与其余代码的区别 - 因此,如果我以后需要可移植,我可以轻松地交换不同的实现。

您可以更进一步,将依赖于 CLR 的代码放入单独的 DLL 中,尽管除非您希望能够单独修补它,否则几乎没有什么附加值。

If you have an existing native C++ app and want to avoid "polluting" it with too much CLR stuff, you can switch on the /clr flag for just one specific file and use a standard C++ header to provide an interface to it. I've done this in an old bit of code. In the header I have:

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

So the rest of the program has a simple API to which it can pass an HICON and a destination filepath.

Then I have a separate source file which is the only one that has /clr switched on:

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
    }
}

That way I can convert HICONs into PNG files from my hairy old C++ program, but I've isolated the use of the .NET framework from the rest of the code - so if I need to be portable later, I can easily swap in a different implementation.

You could take this a stage further and put the CLR-dependent code in a separate DLL, although there would be little added value in that unless you wanted to be able to patch it separately.

叫思念不要吵 2024-08-01 07:06:51

您始终可以在本机应用中托管 CLR

You can always host the CLR in your native app.

爱你是孤单的心事 2024-08-01 07:06:51

C++/CLI in Action 一书有一章名为“混合托管代码和本机代码”在本章中,在使用互操作机制标题下,它讨论了从本机代码访问托管库和从托管代码访问本机库。 当我曾经读过它时,它确实帮助我理解了概念。

The book C++/CLI in Action has a chapter named Mixing Managed and Native Code and inside the chapter, under Working With Interop Mechanisms heading, it talks about both accessing a managed library from native code and accessing a native library from managed code. It did help me get the concepts when I read it once upon a time.

世界和平 2024-08-01 07:06:51

您应该查看非托管导出,您可以将其作为NuGet 包。 这是作者的描述:

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

You should take a look at Unmanaged Exports, which you can get as a NuGet package. This is the description according to the author:

A set of compile-time libraries (nothing to deploy) and a build task that enable you to export functions from managed code to native applications. That means, you can create plugins in a managed language like C# or F# for native applications that only have a C-Api (like Notepad++). The nuget package is all you need. Just mark your methods with [DllExport] and build for x86, x64 or ia64.

兮子 2024-08-01 07:06:51

从 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();

  // ...
}

Calling .NET code from C++/CLI is very straightforward. Its very similar to regular C++. Make sure your project is setup as a C++/CLI project, add a reference to your .NET assembly by going to the project properties under "Common Properties", then use your .NET objects with some code like this:

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

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

  // ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文