代码之家  ›  专栏  ›  技术社区  ›  Rushikesh Talokar

应用程序中的C++

  •  2
  • Rushikesh Talokar  · 技术社区  · 16 年前

    我用C + LIB文件开发C编辑器中的游戏编辑器。 我希望RTTI在C++中使用C++类。 在C++中可以得到C++类的RTTI吗? 如果是,怎么办?

    2 回复  |  直到 16 年前
        1
  •  4
  •   orj    16 年前

    不能将本机C++类型或代码直接暴露在.NET平台上。

    然而,有三种方式与来自.NET的“原生”C++C++代码交互(C语言,VB.NET等等)。

    1. 组件对象模型
    2. 调用/调用
    3. CLI/C++

    从.net的角度来看,com可能是最容易使用的。只需将com对象作为引用添加到.net项目中,然后开始与接口和类交互。有关在.NET中与COM交互的更多详细信息,请阅读以下书籍:

    .NET and COM: The Complete Interoperability Guide http://ecx.images-amazon.com/images/I/51UsCPeI%2BAL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg

    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++代码用委托来调用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。我学到了我所需要的所有关于CLI/C++Office MSDN的知识,但是我听说这本书是好的,如果你喜欢肉的汤姆。

    Expert Visual C++/CLI: .NET for Visual C++ Programmers http://ecx.images-amazon.com/images/I/51iAp1TIXgL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg

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

        2
  •  1
  •   ChrisF    16 年前

    This article 描述过程。

    运行时类型标识(rtti)允许在程序执行期间确定对象的类型。c包含三个支持运行时类型标识的关键字:is、as和typeof。

    你用 is 要确定对象是否属于所需类型,请执行以下操作:

    if (myVariable is string)
    {
         // do stuff
    }
    

    你用 as 从一个对象转换到另一个对象。如果不存在转换,则 null 返回。

    string myString = myVariable as string;
    if (myString != null)
    {
        // do stuff
    }
    

    你用 typeof 获取有关类型的信息。

    要获取表达式的运行时类型,可以使用.net framework方法 GetType .