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#中使用它。这不可能吗?
可以对其进行"不做修改",但您需要一个中间的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类的非确定性破坏。
我建议
- 首先读取CLR程序集
- 不再考虑C++:
- Grok垃圾收集
- Grok标头依赖项、pImpl-idom和gcroot<>
- 现在,从头开始尝试一个C++-CLI库来包装本机库
经过1-2年的[1]丰富的经验,您将能够知道将本机C++库1:1移植到C++-CLI 需要做多少工作
[1] ——好吧,也许你学得很快:)