gpt4 book ai didi

c# - C# 应用程序中的 C++ lib RTTI

转载 作者:搜寻专家 更新时间:2023-10-31 00:48:21 25 4
gpt4 key购买 nike

我正在使用 C++ lib 文件在 C# 中开发游戏编辑器。我想要 C# 中的 C++ 类的 RTTI。是否可以在 C# 中获取 C++ 类的 RTTI?如果是怎么办?

最佳答案

您不能直接向 .NET 平台公开 native C++ 类型或代码。

然而,可以通过三种方式与来自 .NET(C#、VB.Net 或其他语言)的“ native ”C 和 C++ 代码进行交互。

  1. 计算机
  2. P/调用
  3. 命令行/C++

COM 可能是最容易从 .NET 端使用的。只需将 COM 对象作为引用添加到您的 .NET 项目中,然后开始与接口(interface)和类进行交互。有关在 .NET 中与 COM 交互的更多详细信息,请阅读这样一本书:

.NET and COM: The Complete Interoperability Guide

http://www.amazon.com/NET-COM-Complete-Interoperability-Guide/dp/067232170X

这当然需要您将游戏引擎对象公开为 COM 对象。这很重要。

下一个最容易使用的是 P/Invoke。如果您的游戏代码打包在具有 C 调用约定的标准 Windows DLL 中,您可以使用 P/Invoke 访问该 DLL 中的函数。例如:

public static class UserDll
{
[DllImport("user32.dll")]
private static extern bool FlashWindow(IntPtr hwnd, bool bInvert);

public static void FlashWindow(System.Windows.Forms.Form window)
{
FlashWindow(window.Handle, false);
}
}

您可以使用 P/Invoke 做很多事情。甚至让您的 C/C++ 代码通过委托(delegate)和其他方式回调到 C#。

我过去构建过使用 P/Invoke 调用 DLL 中公开的函数的游戏引擎工具。您只需要注意本地资源的管理。在这里,IDisposable 接口(interface)和类终结器成为您的 friend 。例如:

public class Player : IDisposable
{
private IntPtr _thePlayer;

public Player()
{
_thePlayer = CreatePlayer();
}

~Player()
{
Dispose(false);
}

public void Dispose()
{
Dispose(true);
}

private void Dispose(bool disposing)
{
if (disposing)
{
// dispose of managed objects (ie, not native resources only)
}

if (_thePlayer != IntPtr.Empty)
{
DestroyPlayer(_thePlayer);
_thePlayer = IntPtr.Empty;
}
}

[DllImport("gameengine.dll")]
private static extern IntPtr CreatePlayer();

[DllImport("gameengine.dll")]
private static extern void DestroyPlayer(IntPtr player);
}

使用 P/Invoke 有一个缺点。首先,它可以为本地调用增加大量的编码开销(尽管有加快速度的方法)。它还需要 gameengine.dll 中的 C API。如果您的引擎是 C++ 类,则必须为 C++ 类提供 C API。这会增加大量工作(或需要代码生成器)。

我不打算详细介绍处理将托管对象/数据编码到 native 代码和从 native 代码编码的所有杂乱细节。只要知道这是可以做到的,MSDN 是您的 friend 。

将 native C++ 代码公开给 .NET 的第三种可能也是最好的方法是通过 CLI/C++ 混合模式程序集。 CLI/C++ 允许您在单个程序集中相当无缝地混合 native 代码和托管代码。

CLI/C++ 的语法很有趣,但如果您是 C++ 程序员,适应起来并不难。一个例子可能是这样的:

using namespace System;

// CLI/C++ "managed" interface
interface class IDog
{
void Bark();
};

#pragma managed(push off)

// Native C++
class Pet
{
public:
Pet() {}
~Pet() {}

const char* GetNativeTypeName()
{
return typeid(Pet).name();
}
};

#pragma managed(pop)

// CLI/C++ "managed" class
ref class Dog : IDog
{
private:
Pet* _nativePet;

public:
Dog()
: _nativePet(new Pet())
{}
~Dog()
{
delete _nativePet;
_nativePet = 0;
}

void Bark()
{
// Managed code talking to native code, cats & dogs living together, oh my!
Console::WriteLine("Bow wow wow!");

Console::WriteLine(new System::String(_nativePet->GetNativeTypeName()));
}
};

void _tmain()
{
Dog^ d = gcnew Dog();
d->Bark();
}

我的建议(已经完全按照您的意愿去做)是,对于任何超过中等复杂程度的事情,最好的解决方案是尝试为您的游戏引擎提供 CLI/C++ API。我从 MSDN 学到了我需要知道的关于 CLI/C++ 的所有知识,但我听说如果你喜欢内容丰富的大部头,这本书很好。

Expert Visual C++/CLI: .NET for Visual C++ Programmers

http://www.amazon.com/Expert-Visual-CLI-Programmers-Experts/dp/1590597567

关于c# - C# 应用程序中的 C++ lib RTTI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2721633/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com