包装 C++ 以在 C# 中使用 [英] Wrapping C++ for use in C#

查看:36
本文介绍了包装 C++ 以在 C# 中使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,基本上有一个大型 C++ 项目 (Recast) 我想包装以便我可以在我的 C# 项目中使用它.

Ok, basically there is a large C++ project (Recast) that I want to wrap so that I can use it in my C# project.

我已经尝试这样做了一段时间了,这就是我目前所做的.我正在使用 C++/CLI 来包装我需要的类,以便我可以在 C# 中使用它们.

I've been trying to do this for a while now, and this is what I have so far. I'm using C++/CLI to wrap the classes that I need so that I can use them in C#.

但是,我的 C# 项目中还需要大量的结构体和枚举.那么我该如何包装这些呢?

However, there are a ton of structs and enums that I will also need in my C# project. So how do I wrap these?

我现在使用的基本方法是向本机 C++ 代码添加 dllexport 调用,编译为 dll/lib,将此库添加到我的 C++/CLI 项目并导入 C++ 头文件,然后将 CLI 项目编译为dll,最后添加这个 dll 作为对我的 C# 项目的引用.感谢您的帮助.

The basic method I'm using right now is adding dllexport calls to native c++ code, compiling to a dll/lib, adding this lib to my C++/CLI project and importing the c++ headers, then compiling the CLI project into a dll, finally adding this dll as a reference to my C# project. I appreciate any help.

这是一些代码..我需要一个可管理的方法来做到这一点,因为 C++ 项目太大了.

Here is some code..I need manageable way of doing this since the C++ project is so large.

//**Native unmanaged C++ code
//**Recast.h

enum rcTimerLabel
{
   A,
   B,
   C
};

extern "C" {

class __declspec(dllexport) rcContext
{
   public:
   inline rcContect(bool state);
   virtual ~rcContect() {}
   inline void resetLog() { if(m_logEnabled) doResetLog(); }

   protected:
   bool m_logEnabled;
}

struct rcConfig
{
   int width;
   int height;
}

} // end of extern


// **Managed CLI code
// **MyWrappers.h
#include "Recast.h"

namespace Wrappers
{
   public ref class MyWrapper
   {
   private:
     rcContect* _NativeClass;
   public:
     MyWrapper(bool state);
     ~MyWrapper();
     void resetLog();
     void enableLog(bool state) {_NativeClass->enableLog(state); }
   };
}

//**MyWrapper.cpp
#include "MyWrappers.h"

namespace Wrappers
{
   MyWrapper::MyWrapper(bool state)
   {
      _NativeClass = new rcContext(state);
   }

   MyWrapper::~MyWrapper()
   {
      delete _NativeClass;
   }
   void MyWrapper::resetLog()       
   {
      _NativeClass->resetLog();
   }
}


// **C# code
// **Program.cs

namespace recast_cs_test
{
   public class Program
   {
      static void Main()
      {
          MyWrapper myWrapperTest = new MyWrapper(true);
          myWrapperTest.resetLog();
          myWrapperTest.enableLog(true);
      }
   }
}

推荐答案

通常,C/C++ 结构用于与本机代码通信,而您创建 CLI 类用于与 .NET 代码通信.C 结构体是愚蠢的"因为它们只能存储数据.另一方面,.NET 程序员希望他们的数据结构是智能的".例如:

As a rule, the C/C++ structs are used for communicating with the native code, while you create CLI classes for communicating with the .NET code. C structs are "dumb" in that they can only store data. .NET programmers, on the other hand, expect their data-structures to be "smart". For example:

如果我改变高度"结构中的参数,我知道对象的高度实际上不会改变,直到我将该结构传递给更新函数.但是,在 C# 中,常见的习惯用法是将值表示为属性,更新属性将立即使这些更改生效".

If I change the "height" parameter in a struct, I know that the height of the object won't actually change until I pass that struct to an update function. However, in C#, the common idiom is that values are represented as Properties, and updating the property will immediately make those changes "live".

那样我可以做这样的事情:myshape.dimensions.height = 15 并且只期望它工作".

That way I can do things like: myshape.dimensions.height = 15 and just expect it to "work".

在某种程度上,您向 .NET 开发人员公开的结构(作为类)实际上是 API,行为被映射到这些类的属性和方法.而在 C 中,这些结构只是用作传递给执行工作的函数和从执行工作的函数传出的变量.换句话说,.NET 通常是一种面向对象的范式,而 C 则不是.许多 C++ 代码实际上是 C 语言,只是为了调味而加入了一些花哨的内容.

To a certain extent, the structures you expose to the .NET developer (as classes) actually ARE the API, with the behaviors being mapped to properties and methods on those classes. While in C, the structures are simply used as variables passed to and from the functions that do the work. In other words, .NET is usually an object-oriented paradigm, while C is not. And a lot of C++ code is actually C with a few fancy bits thrown in for spice.

如果您正在编写 C 和 .NET 之间的翻译层,那么您工作的很大一部分就是设计将构成您的新 API 的对象,并为您的底层功能提供翻译.C 代码中的结构不一定是新对象层次结构的一部分;它们只是 C API 的一部分.

If you're writing translation layer between C and .NET, then a big part of your job is to devise the objects that will make up your new API and provide the translation to your underlying functionality. The structs in the C code aren't necessarily part of your new object hierarchy; they're just part of the C API.

编辑添加:

此外,您可能需要重新考虑使用 C++/CLI 的选择,并考虑使用 C# 和 p/invoke.出于各种原因,我曾经使用 C++/CLI 为 OpenSSL 编写了一个包装器,虽然令人印象深刻的是它的构建是多么容易并且它是多么无缝地工作,但还是有一些烦恼.具体来说,绑定很紧,所以每次父项目 (OpenSSL) 更新他们的库时,我都必须重新编译我的包装器以匹配.此外,我的包装器永远绑定到特定架构(64 位或 32 位),该架构也必须与底层库的构建架构相匹配.您仍然会遇到 p/invoke 的架构问题,但它们更容易处理.此外,C++/CLI 不能很好地与 Reflector 等内省工具配合使用.最后,您构建的库不可移植到 Mono.我没想到这最终会成为一个问题.但最后,我不得不从头开始,使用 p/invoke 用 C# 重新完成整个项目.

Also, you may want to re-consider your choice to use C++/CLI and consider C# and p/invoke instead. For various reasons, I once wrote a wrapper for OpenSSL using C++/CLI, and while it was impressive how easy it was to build and how seamless it worked, there were a few annoyances. Specifically, the bindings were tight, so every time the the parent project (OpenSSL) revved their library, I had to re-compile my wrapper to match. Also, my wrapper was forever tied to a specific architecture (either 64-bit or 32-bit) which also had to match the build architecture of the underlying library. You still get architecture issues with p/invoke, but they're a bit easier to handle. Also, C++/CLI doesn't play well with introspection tools like Reflector. And finally, the library you build isn't portable to Mono. I didn't think that would end up being an issue. But in the end, I had to start over from scratch and re-do the entire project in C# using p/invoke instead.

一方面,我很高兴我做了 C++/CLI 项目,因为我在一个项目中学到了很多关于使用托管和非托管代码和内存的知识.但另一方面,我肯定有很多时间可以花在其他事情上.

On the one hand, I'm glad I did the C++/CLI project because I learned a lot about working with managed and unmanaged code and memory all in one project. But on the other hand, it sure was a lot of time I could have spent on other things.

这篇关于包装 C++ 以在 C# 中使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆