在C ++中定义一个需要在C#和C ++中实现的接口

时间:2020-03-05 18:53:57  来源:igfitidea点击:

我有一个用C ++定义的接口,现在需要用C#实现。最好的方法是什么?我根本不想在接口定义中使用COM。我现在解决此问题的方法是有两个接口定义,一个在C ++中,一个在C#中。然后,我将Cinterfaces公开为COM服务器。这是我的用C ++编写的应用程序,可以调用C#。无论如何,我可以避免不得不在C ++和C#中定义我的实现吗?

解决方案

回答

我们为什么不想使用COM?

这本来是我的建议。 COM互操作对我来说确实非常有效,并且我在C中使用了COM对象和接口(只需引用COM对象,即可自动创建运行时可调用包装器)。类似地,将Cclass标记为"注册COM互操作"的方法也相反。

回答

如果我们愿意将C ++ / CLI用于托管代码而不是C#,则可以直接通过头文件使用本机C ++接口定义。这将有多容易取决于界面中最简单的情况,我们可以在C语言中使用。

看看Marcus Heege的Expert C ++ / CLI:.NET for Visual C ++程序员,可以获得有关在.NET中混合本机和托管C ++的许多有用信息。

回答

用C ++编写接口,并使用宏使其在UNIX上看起来像标准cpp头文件,在Windows上看起来像IDL文件(如果无法解决,我们可以随时编写python / ruby​​脚本从C ++头文件)。

编译IDL以生成typelib。使用TypeLib Importer生成接口定义,以便Cand在此处实现接口。

回答

用IDL编写接口,并使用工具将接口编译为目标语言。在研究与跨语言接口有关的CORBA时,我们可能会找到指向此对象的指针。

/艾伦

回答

我们没有提到正在使用哪个版本的.NET,但是在使用Visual Studio .NET 2003时对我有用的一点是围绕实际C ++类的简单实现提供了一个瘦Cwrapper:

public __gc class MyClass_Net {
public:
   MyClass_Net()
      :native_ptr_(new MyClass())
   {
   }
   ~MyClass_Net()
   {
      delete native_ptr_;
   }

private:
   MyClass __nogc *native_ptr_;
};

显然,有人希望在那里使用Boost Boost_shared_ptr,但是我永远无法让它们在V.NET 2003中很好地玩...

方法仅通过指针转发给基础C ++方法。方法参数可能必须转换。例如,要调用使用字符串的C ++方法,则Cmethod可能应该使用System.String(托管C ++中的System :: String)。我们必须使用System :: Runtime :: InteropServices :: Marshal :: StringToHGlobalAnsi()来执行此操作。

这种方法的优点是,由于托管C ++是.NET语言,因此我们可以将访问器公开为属性(__property)。我们甚至可以公开属性,就像在C#中一样。

回答

另一种方法是使用"扁平"的C风格的API。我们也可以使用extern" C"来防止意外重载。使用DEF文件显式命名导出的函数,因此绝对不会以任何方式修饰它们(C ++函数在导出表中使用参数类型的编码进行"修饰")。

在x86上,请注意调用约定。可能要明确声明使用__stdcall或者__cdecl。因为P / Invoke主要用于调用Windows API,所以它默认为StdCall,但是C和C ++默认为cdecl,因为它支持varargs。

我最近将COM接口IRapiStream封装在一个平面C接口中,因为.NET似乎正试图将IStream转换为存储,但由于错误STG_E_UNIMPLEMENTEDFUNCTION而失败。

回答

Swig是用其他语言(如C#)包装C ++类的好工具。