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

时间:2011-01-06 14:28:30

标签: c# c c++-cli

我使用C ++ / CLI包装C库,以便可以通过C#方式轻松地从C#中使用C库。

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

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

我有两个相关的问题:

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

  2. 有没有更好的方法来包装这些函数,比如使用Generic? [我开始使用模板专业化但后来意识到C#没有看到模板。]

  3. 感谢。

    修改

    如何实现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失败,显然案例无效。怎么解决?

3 个答案:

答案 0 :(得分:2)

你可能比使用代表字典更糟糕,按类型键入(对不起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

答案 1 :(得分:2)

如下所示的一些重载...

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);
        }
    }
};

显然,你需要进行一些转换,并对String进行适当的编组 - &gt; char *转换,但你明白了。

已修改为包含类型检测

答案 2 :(得分:1)

我不能使用开关,因为在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
}