C++;C#应用程序中的lib-RTTI 我在C++开发游戏编辑器,使用C++的LIB文件。 我希望RTTI在C++中使用C++类。 在C++中可以得到C++类的RTTI吗? 如果是,如何描述该过程
运行时类型标识(RTTI)允许在程序执行期间确定对象的类型。C#包括三个支持运行时类型标识的关键字:is、as和typeof 用于确定对象是否为所需类型:C++;C#应用程序中的lib-RTTI 我在C++开发游戏编辑器,使用C++的LIB文件。 我希望RTTI在C++中使用C++类。 在C++中可以得到C++类的RTTI吗? 如果是,如何描述该过程,c#,c++,rtti,C#,C++,Rtti,运行时类型标识(RTTI)允许在程序执行期间确定对象的类型。C#包括三个支持运行时类型标识的关键字:is、as和typeof 用于确定对象是否为所需类型: if (myVariable is string) { // do stuff } 用于从一个对象转换为另一个对象。如果不存在转换,则返回null string myString = myVariable as string; if (myString != null) { // do stuff } 用于获取有关类型的
if (myVariable is string)
{
// do stuff
}
用于从一个对象转换为另一个对象。如果不存在转换,则返回null
string myString = myVariable as string;
if (myString != null)
{
// do stuff
}
用于获取有关类型的信息
要获取表达式的运行时类型,可以使用.NET Framework方法
不能直接将本机C++类型或代码暴露到.NET平台。 然而,与.NET(C++语言、VB语言、网络语言或其他语言)中的“原生”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();
}
这当然要求您将游戏引擎对象公开为COM对象。这不是小事
下一个最容易使用的是p/Invoke。如果游戏代码打包在标准windows DLL中,并带有C调用约定,则可以使用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++代码调用到C#中,包括委托之类的
我以前构建过游戏引擎工具,它使用p/Invoke调用DLL中公开的函数。你只需要小心管理本地资源。在这里,IDisposable接口和类终结器将成为您的朋友。例如:
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。这可能会增加大量工作(或者需要一个代码生成器)
我不打算详细讨论处理托管对象/数据与本机代码之间的编组的所有混乱细节。只要知道这是可以做到的,MSDN是你在这里的朋友
第三种可能是将C++代码暴露到.NET的最好方式是通过CLI/C++混合模式程序集。CLI/C++允许您在单个程序集中非常无缝地混合本机代码和托管代码
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++的知识,但我听说如果你喜欢肉感的大部头,这本书很好
谢谢您的回复。但你没有明白我的问题。我想在C++中导入C++ LIB文件类RTTI。@ Rushi -对不起,从你的问题看不清楚。也许你应该举一个你想要实现的例子。