visual c++-使用/clr编译现有的c++代码,然后从c#调用它

本文关键字:然后 代码 调用 c++ 使用 c++- clr 编译 visual | 更新日期: 2023-09-27 18:00:09

我有一些C++代码:

namespace Compute {
  class __declspec(dllexport) IProgressCB {
  public:
    virtual void progress(int percentCompleted) = 0;
  };
  double __declspec(dllexport) compute(IProgressCB *progressCB, ...);
}

在Visual Studio 2008中打开"公共语言运行时支持(/clr)"的情况下,我从中创建了"compute.dll"。

我想从C#调用这个代码。

接下来,我创建了一个C#控制台应用程序,并添加compute.dll作为参考。然后我尝试子类化/实现IProgressCB:

public class Progress : Compute.IProgressCB
{
    public void progress(int percentCompleted)
    {
        Console.WriteLine(percentCompleted + "% completed.");
    }
}

然而,VS的自动完成可以找到"Compute"命名空间,但不能找到其中的任何类或函数!?当我试图编译时;它抱怨IProgressCB没有公开。如果我在IProgressCB声明之前编写public,它会抱怨无法从密封类型"Compute.IProgressCB"派生。

我在这里做错了什么?我想使用现有的C++代码,不对其进行任何修改,但使用/clrc编译它,然后从C#中使用它。这不可能吗?

visual c++-使用/clr编译现有的c++代码,然后从c#调用它

可以对其进行"不做修改",但您需要一个中间的C++/CLI层来包装现有代码。C#和其他CLR语言只能"看到"托管类型,即ref类、值类等。简单地将/CLR应用于现有的代码库将无法不编写任何额外的C++代码。

IProgressCB必须是一个托管类才能从C#中可见。

public ref class IProgressCB
{
    // ...
};  

这样一来,IProgressCB的工作方式将与以前大不相同,尤其是内存管理现在完全不同了。

您可以使用C++/CLI为现有的非托管类编写托管包装器,但不要指望只需在编译器开关中添加"/clr"就可以直接使用C#中的非托管C++类。阅读本文

http://weblogs.asp.net/kennykerr/archive/2005/07/12/Mixing-Native-and-Managed-Types-in-C_2B002B00_.aspx

了解如何将数据从一个世界传输到另一个世界,反之亦然。

很明显,C++-CLI(C++托管扩展的成功者)与C++不同。命名空间成员的可见性只是差异的一小部分。

最大的失误将是ref类的非确定性破坏。

我建议

  1. 首先读取CLR程序集
  2. 不再考虑C++:
  3. Grok垃圾收集
  4. Grok标头依赖项、pImpl-idom和gcroot<>
  5. 现在,从头开始尝试一个C++-CLI库来包装本机库

经过1-2年的[1]丰富的经验,您将能够知道将本机C++库1:1移植到C++-CLI 需要做多少工作

[1] ——好吧,也许你学得很快:)

相关文章: