C++;互操作:如何从本机C++;,扭曲类是非静态的吗? 我有一个用C++编写的大型应用程序。我还有一门C#课程需要打电话

C++;互操作:如何从本机C++;,扭曲类是非静态的吗? 我有一个用C++编写的大型应用程序。我还有一门C#课程需要打电话,c#,c++,interop,c++-cli,C#,C++,Interop,C++ Cli,如果C#类是静态的,那么它就很简单(web上有很多示例)-只需编写混合的C++/CLI包装器,导出接口,就完成了 但是,C#类是非静态的,并且不能更改为静态的,因为它有一个接口(如果您试图使C#类成为静态的,编译器将生成一个错误) 有没有人遇到过这个问题——我如何导出非静态C++类到本机C++?< /p> 更新2010-11-09 最后一个解决方案:尝试了COM,它工作得很好,但不支持结构。所以,用C++/CLI包装器,因为我绝对需要能够在C++和C++之间传递结构。我根据下面的代码编写了一个

如果C#类是静态的,那么它就很简单(web上有很多示例)-只需编写混合的C++/CLI包装器,导出接口,就完成了

但是,C#类是非静态的,并且不能更改为静态的,因为它有一个接口(如果您试图使C#类成为静态的,编译器将生成一个错误)

有没有人遇到过这个问题——我如何导出非静态C++类到本机C++?< /p>


更新2010-11-09

最后一个解决方案:尝试了COM,它工作得很好,但不支持结构。所以,用C++/CLI包装器,因为我绝对需要能够在C++和C++之间传递结构。我根据下面的代码编写了一个混合模式.dll包装器:

由于目标类是非静态的,我必须使用singleton模式来确保我只实例化了目标类的一个副本。这确保了一切都足够快,以满足规格

如果你想让我发布演示项目(尽管公平,我从C++调用C++),现在大多数人都想从C++调用C++(.c++)。使用C++/CLI,您只需引用保存非静态类的程序集,然后可以使用
gcnew
获取对新实例的引用

是什么让您认为这在非静态类中是不可能的

编辑:这里有示例代码

使用名称空间系统;
公共参考等级CSquare
{
私人:
双sd;
公众:
CSquare():sd(0.00){}
CSquare(双面):sd(侧面){}
~CSquare(){}
物业双面
{
双get(){return sd;}
空集(双s)
{
如果(s)侧=5.62;
sqrs[1]=gcnew CSquare;
sqrs[1]->侧=770.448;
sqrs[2]=GCC新的CSquare;
sqrs[2]>Side=2442.08;
sqrs[3]=新的GCSquare;
sqrs[3]->侧=82.304;
sqrs[4]=gcnew CSquare;
sqrs[4]->侧=640.1115;
返回SQR;
}

我想到了两个选项

将类作为COM对象公开并将其作为COM对象从C++中使用。
  • 创建一个静态C#类,该类公开了一个与非静态C#类交互的接口

  • 几年前我研究过这个主题:我想使用log4net和Npgsql库,这些库来自本机代码,即使没有/clr键也可以编译

    Paul DiLascia在其两篇杰出的文章中描述了这种技术背后的主要思想:

    该解决方案的主要思想是gcroot智能指针和intptr__在内存中具有完全相同的表示形式。我们创建了一个名为gcroot(t)的宏,它在托管代码中使用gcroot,在非托管代码中使用intptr_________________________________


    <> P> >我很容易为我的托管类创建一些适配器,并在本地C++世界中使用它们,甚至在没有/CLR键的情况下编译我的源代码。

    我知道我需要在几周内完成这项任务,所以我对答案非常感兴趣。该死,这是一个类似于锯齿的扭曲。在问题的最后,当你最不希望的时候,我决定和CO一起去。M、 非常感谢您花时间回答这个问题-非常感谢。我决定使用COM。我们感兴趣的是,您知道C++/CLI包装器在C#中实例化非静态类的任何示例吗?无论我做了什么尝试,我都无法回避编译器错误,而且web的任何示例都不是针对除了静态类以外的任何东西。非常好,谢谢。为了完整起见,您参考的源代码是为MSVS 2003设计的,除非升级到MSVS 2005,说明和更新的源代码位于(谢谢@Sergey)。最终使用C++/CLI来支持结构。请参阅主要问题中的编辑。我看了您引用的代码,它看起来非常易于使用:我将实现COM和上面的代码,并编辑我的原始问题以更正它。非常感谢!
    using namespace System;
    
    public ref class CSquare
    {
    private:
        double sd;
    
    public:
        CSquare() : sd(0.00) {}
        CSquare(double side) : sd(side) { }
        ~CSquare() { }
    
        property double Side
        {
        double get() { return sd; }
        void set(double s)
        {
            if( s <= 0 )
            sd = 0.00;
            else
            sd = s;
        }
        }
    
        property double Perimeter { double get() { return sd * 4; } }
        property double Area { double get() { return sd * sd; } }
    };
    
    array<CSquare ^> ^ CreateSquares()
    {
        array<CSquare ^> ^ sqrs = gcnew array<CSquare ^>(5);
    
        sqrs[0] = gcnew CSquare;
        sqrs[0]->Side = 5.62;
        sqrs[1] = gcnew CSquare;
        sqrs[1]->Side = 770.448;
        sqrs[2] = gcnew CSquare;
        sqrs[2]->Side = 2442.08;
        sqrs[3] = gcnew CSquare;
        sqrs[3]->Side = 82.304;
        sqrs[4] = gcnew CSquare;
        sqrs[4]->Side = 640.1115;
    
        return sqrs;
    }