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

有帮助吗?

解决方案

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

看看马库斯·希吉的 专家 C++/CLI:面向 Visual C++ 程序员的 .NET, ,了解有关在 .NET 中混合本机 C++ 和托管 C++ 的大量有用信息。

其他提示

痛饮 是一个用 C# 等其他语言包装 C++ 类的好工具。

为什么不想使用COM?

这是我的建议。COM 互操作对我来说非常有效,并且我在 C# 中使用了 COM 对象和接口(只需引用 COM 对象,运行时可调用包装器就会自动创建)。同样,将 C# 类标记为“注册 COM 互操作”也有相反的效果。

用 C++ 编写接口并使用宏使其看起来像 UNIX 上的标准 cpp 头文件和 Windows 上的 IDL 文件(如果这不起作用,您始终可以编写一个 python/ruby 脚本来从C++ 头文件)。

编译 IDL 以生成类型库。使用 TypeLib Importer 生成 C# 的接口定义并在那里实现接口。

用IDL编写接口并使用工具将接口编译为目标语言。在研究涉及跨语言接口的 CORBA 时,您可能会找到这方面的指示。

/艾伦

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

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

我最近封装了COM接口 IRapiStream 在平面 C 接口中,因为 .NET 似乎试图将 IStream 转换为存储,但失败并出现错误 STG_E_UNIMPLEMENTEDFUNCTION.

您没有提及您正在使用哪个版本的 .NET,但是在使用 Visual Studio .NET 2003 时对我有用的东西是为真正的 C++ 类的粗糙实现提供一个薄的 C# 包装器:

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

private:
   MyClass __nogc *native_ptr_;
};

显然,人们更愿意在那里使用 Boost shared_ptr,但我永远无法让它们与 V.NET 2003 很好地配合...

方法只是通过指针转发到底层 C++ 方法。方法参数可能需要转换。例如,要调用采用字符串的 C++ 方法,C# 方法可能应采用 System.String(托管 C++ 中的 System::String)。您必须使用 System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi() 来执行此操作。

这种方法的一个好处是,因为托管 C++ 是一种 .NET 语言,所以您可以将访问器公开为属性 (__property)。您甚至可以公开属性,就像在 C# 中一样。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top