单个 C++/CLI 方法可包装许多类型特定的 C 函数

发布于 2024-10-10 08:17:16 字数 885 浏览 0 评论 0原文

我正在使用 C++/CLI 包装 C 库,以便可以以 C# 风格的方式从 C# 轻松使用 C 库。

该库中的一些函数用于将值放入容器中。 C 中没有泛型,因此每种类型都存在一个函数 CLIB_SetBool(BOOL value)、CLIB_SetInt(int value)、CLIB_SetString(char* string) 等。

为了更容易在 C# 中使用,我创建了一个采用 System::Object 的 Set 函数。

我有两个相关问题:

  1. 通过我的方法,您将如何在 System::Object 类型上使用 switch 语句来调用正确的 CLIB_Setxxxx 函数。 [typeid 仅适用于非托管代码,我似乎无法使用 GetType。]

  2. 是否有更好的方法来包装这些函数,例如使用泛型? [我开始使用模板专门化,但后来意识到 C# 看不到模板。]

谢谢。

编辑

如何实现 void Set(System::Object^ value) ?

我想做类似的事情:

void MyWrapper::Set(System::Object^ value)
{
 switch(typeid(value))
  {
   case System::Int32:  CLIB_SetInt(MyMarshal<clib_int>(value));    break;
   case System::Double: CLIB_SetInt(MyMarshal<clib_double>(value)); break;
//and so on
}
}

托管代码的 typeid 失败,并且显然这些情况无效。如何修复?

I am wrapping a C library using C++/CLI so that the C library can be used easily from C# in a C#'ish way.

Some of the functions in this library are for putting a value into a container. There are no generics in C so there exists a function per type CLIB_SetBool(BOOL value), CLIB_SetInt(int value), CLIB_SetString(char* string) and so on.

To make it easier to use from C#, I have created a single Set function which takes a System::Object.

I have two related questions:

  1. With my method how would you use a switch statement on the type of System::Object to call the correct CLIB_Setxxxx function. [typeid is only for unmanaged code and I can't seem to use GetType.]

  2. Is there a better way to wrap these functions like using a Generic? [I started using template specialisation but then realised that C# doesn't see templates.]

Thanks.

EDIT

How do I implement void Set(System::Object^ value) ?

I want to do something like:

void MyWrapper::Set(System::Object^ value)
{
 switch(typeid(value))
  {
   case System::Int32:  CLIB_SetInt(MyMarshal<clib_int>(value));    break;
   case System::Double: CLIB_SetInt(MyMarshal<clib_double>(value)); break;
//and so on
}
}

The typeid fails for managed code and clearly the cases are invalid. How to fix?

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

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

发布评论

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

评论(3

灼疼热情 2024-10-17 08:17:16

您可能会比使用按类型键控的委托字典做得更糟糕(抱歉 C# 语法,自从我使用 C++/CLI 以来已经有一段时间了)。当然,在每个委托中,您实际调用相应的 C 函数。

public delegate void CLIBDelegate(object);


// handlers for types that will call the appropriate CLIB_XXX function:
public void CLIB_int(object _obj);
public void CLIB_string(object _obj);
// etc...


// Our dictionary:
Dictionary<System.Type, CLIBDelegate> dict = new Dictionary<System.Type, CLIBDelegate>();
dict[typeof(System.Int32)] = CLIB_int;
dict[typeof(System.string] = CLIB_string;
// etc...


// your set function
void Set(Object _object)
{
    if(dict.ContainsKey(_object.GetType())
        dict[_object.GetType()](_object);
} // eo Set

You could do worse than utilize a dictionary of delegates, keyed by type (Sorry for C# syntax, it's been a while since I did C++/CLI). Within each delegate, of course, you make your actual call to the appropriate C function.

public delegate void CLIBDelegate(object);


// handlers for types that will call the appropriate CLIB_XXX function:
public void CLIB_int(object _obj);
public void CLIB_string(object _obj);
// etc...


// Our dictionary:
Dictionary<System.Type, CLIBDelegate> dict = new Dictionary<System.Type, CLIBDelegate>();
dict[typeof(System.Int32)] = CLIB_int;
dict[typeof(System.string] = CLIB_string;
// etc...


// your set function
void Set(Object _object)
{
    if(dict.ContainsKey(_object.GetType())
        dict[_object.GetType()](_object);
} // eo Set
熊抱啵儿 2024-10-17 08:17:16

下面的一些重载怎么样?

ref class CLIB_Wrapper
{
    static void Set(System::Boolean^ value) { CLIB_SetBool(*value); }
    static void Set(System::Int32^ value) { CLIB_SetInt(*value); }
    static void Set(System::String^ value) { CLIB_SetString(*value); }

    static void Set(System::Object^ value)
    {
        System::Type^ type = value->GetType();
        if( type == System::Boolean::typeid )
        {
            Set((System::Boolean^)value);
        }
        else if( type == System::Int32::typeid )
        {
            Set((System::Int32^)value);
        }
        else if( type == System::String::typeid )
        {
            Set((System::String^)value);
        }
    }
};

显然,您需要在其中进行一些转换,并为字符串进行适当的编组 -> char* 转换,但你明白了。

进行编辑以包括类型检测

What about some overloads as follows..

ref class CLIB_Wrapper
{
    static void Set(System::Boolean^ value) { CLIB_SetBool(*value); }
    static void Set(System::Int32^ value) { CLIB_SetInt(*value); }
    static void Set(System::String^ value) { CLIB_SetString(*value); }

    static void Set(System::Object^ value)
    {
        System::Type^ type = value->GetType();
        if( type == System::Boolean::typeid )
        {
            Set((System::Boolean^)value);
        }
        else if( type == System::Int32::typeid )
        {
            Set((System::Int32^)value);
        }
        else if( type == System::String::typeid )
        {
            Set((System::String^)value);
        }
    }
};

Obviously you'll need some conversions in there with appropriate marshalling for the String -> char* conversion, but you get the idea.

Edited to include detection of type

天暗了我发光 2024-10-17 08:17:16

我无法使用开关,因为托管代码似乎没有像 C++ 那样的完整类型表示。

以下作品。

void MyWrapper::Set(System::Object^ value)
{
  if (value->GetType() == System::Int32::typeid)
  {
      CLIB_SetInt(MyMarshal<clib_int>(value));
  }  
  else if ((value->GetType() == System::Double::typeid)
  {
      CLIB_SetDouble(MyMarshal<clib_double>(value));
  }
//etc
}

I can't use a switch because there doesn't seem to be an integral representation of type for managed code as there is in C++.

The following works.

void MyWrapper::Set(System::Object^ value)
{
  if (value->GetType() == System::Int32::typeid)
  {
      CLIB_SetInt(MyMarshal<clib_int>(value));
  }  
  else if ((value->GetType() == System::Double::typeid)
  {
      CLIB_SetDouble(MyMarshal<clib_double>(value));
  }
//etc
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文