简体   繁体   English

C ++ Interop:如何从本机C ++调用C#类,这个类是非静态的?

[英]C++ Interop: How do I call a C# class from native C++, with the twist the class is non-static?

I have a large application written in native C++. 我有一个用本机C ++编写的大型应用程序。 I also have a class in C# that I need to call. 我还有一个C#课,我需要打电话。

If the C# class was static, then it would be trivial (there's lots of examples on the web) - just write the mixed C++/CLI wrapper, export the interfaces, and you're done. 如果C#类是静态的,那么它将是微不足道的(Web上有很多例子) - 只需编写混合的C ++ / CLI包装器,导出接口,然后就完成了。

However, the C# class is non-static, and can't be changed to static as it has an interface (the compiler will generate an error if you attempt to make the C# class static). 但是,C#类是非静态的,并且不能更改为静态,因为它有一个接口(如果您尝试使C#类静态,编译器将生成错误)。

Has anyone run into this problem before - how do I export a non-static C# class to native C++? 有没有人遇到过这个问题 - 如何将非静态C#类导出到本机C ++?


Update 2010-11-09 更新2010-11-09

Final solution: tried COM, this worked nicely but didn't support structures. 最终的解决方案:尝试COM,这很好用,但不支持结构。 So, went with a C++/CLI wrapper, because I absolutely needed to be able to pass structures between C++ and C#. 所以,使用C ++ / CLI包装器,因为我绝对需要能够在C ++和C#之间传递结构。 I wrote a mixed mode .dll wrapper based on the code here: 我根据这里的代码编写了一个混合模式.dll包装器:

As the target class was non-static, I had to use the singleton pattern to make sure I was only instantiating one copy of the target class. 由于目标类是非静态的,我不得不使用单例模式来确保我只是实例化目标类的一个副本。 This ensured everything was fast enough to meet the specs. 这确保了一切都足够快,以满足规格。

Contact me if you want me to post a demo project (although, to be fair, I'm calling C# from C++, and these days most people want to call C++ from C#). 如果你想让我发布一个演示项目,请联系我(虽然,公平地说,我从C ++调用C#,而现在大多数人都希望从C#调用C ++)。

C++/CLI or COM interop work just as well with non-static classes as with static. 与静态类一样,C ++ / CLI或COM互操作也适用于非静态类。 Using C++/CLI you just reference your assembly that holds the non-static class and then you can use gcnew to obtain a reference to a new instance. 使用C ++ / CLI,您只需引用包含非静态类的程序集,然后您可以使用gcnew来获取对新实例的引用。

What makes you think that this is not possible with your non-static class? 是什么让你认为这对你的非静态课是不可能的?

EDIT: there is example code here . 编辑:有示例代码在这里

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;
}

Two options come to mind. 我想到了两种选择。

  1. Expose the class as a COM object and use it as a COM object from C++. 将该类公开为COM对象,并将其用作C ++中的COM对象。
  2. Create a static C# class that exposes an interface to interact with the non-static C# class. 创建一个静态C#类,它公开了一个与非静态C#类交互的接口。

I've investigated this topic couple of years ago: I want to use log4net and Npgsql libraries from native code that compiles even without /clr key. 几年前我已经调查了这个主题:我想使用原生代码中的log4net和Npgsql库,即使没有/ clr密钥也可以编译。

The main idea behind this technique described by Paul DiLascia in his two remarkable articles: Paul DiLascia在他的两篇引人注目的文章中描述了这种技术背后的主要思想:

Managed Code in Visual Studio 2005 Visual Studio 2005中的托管代码

Use Our ManWrap Library to Get the Best of .NET in Native C++ Code 使用我们的ManWrap库在Native C ++代码中获得最佳.NET

The main idea in this solution that gcroot smart pointer and intptr_t have exactly the same representation in memory. 这个解决方案的主要思想是gcroot智能指针和intptr_t在内存中具有完全相同的表示。 And we creating a macro called GCROOT(T) that uses gcroot in Managed code and intptr_t in unmanaged. 我们创建了一个名为GCROOT(T)的宏,它在托管代码中使用gcroot,在非托管代码中使用intptr_t。 And that we create DLL with native interface and managed implementation and uses this dll from our native code. 我们使用本机接口和托管实现创建DLL,并使用本机代码中的dll。

It was pretty easy for me create some adapter for my managed classes and use them in native C++ world and compile my source code even without /clr key. 我很容易为托管类创建一些适配器并在本机C ++世界中使用它们,即使没有/ clr密钥也可以编译我的源代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM