从C ++ / CLI函数调用C#函数

时间:2015-05-29 21:26:21

标签: c# c++ c++-cli interop marshalling

我的项目要求我使用C#为C ++提供用户界面。我调用的一个C ++函数做了很多工作,并通过另一个“对象”提供定期进度更新。这是我的意思的一个例子。

C ++

class AppDelegate : public ProgressDelegate
    {
    void AppDelegate::UpdateStatusText(const char* text)
        {
        // Go() will end up calling me at some point.
        OutputDebugString(text);
        }
    void AppDelegate::ShowMessage(const char* text)
        {
        // Go() will end up calling me at some point.
        OutputDebugString(text);
        }
     };

int CppWrapper::Go()
    {
    return cppInstance->Go()
    }

CSHARP

void UpdateStatusText(String text)
   {
   //update UI
   }
void ShowMessage(String text)
   {
   //update UI
   }

我想要做的是使用updateStatusText和ShowMessage并将文本传递给C#以更新我的UI。我的问题是如何公开适当的C#方法,以便我的C ++代码可以调用它们?请注意,修改Go不是我的选择。

3 个答案:

答案 0 :(得分:1)

也许这个例子可以帮到你:

编写托管DLL

要创建一个简单的托管DLL,它具有一个公共方法来添加两个数字并返回结果,请按照下列步骤操作:

启动Microsoft Visual Studio .NET或Microsoft Visual Studio 2005。 在“文件”菜单上,指向“新建”,然后单击“项目”。将打开“新建项目”对话框。 在“项目类型”下,单击“Visual C#Projects”。

注意在Visual Studio 2005中,单击“项目类型”下的“Visual C#”。 在“模板”下,单击“类库”。 在“名称”文本框中,键入sManagedDLL,然后单击“确定”。 在代码视图中打开Class1.cs文件。 要声明具有添加两个数字的方法的公共接口,请将以下代码添加到Class1.cs文件中:

$(document).foundation();
$(document).ready(function(){
    $('a.open-first').hover(function(){
        $('#first-modal').foundation('reveal', 'open');
    });
});

要在类中实现此公共接口,请将以下代码添加到Class1.cs文件中:

// Interface declaration.
public interface ICalculator
{
    int Add(int Number1, int Number2);
};

注册托管DLL以与COM或Native C ++一起使用 若要将托管DLL与COM或本机C ++一起使用,必须在Windows注册表中注册DLL的程序集信息。为此,请按照下列步骤操作:

从Native C ++代码调用托管DLL

// Interface implementation.
public class ManagedClass:ICalculator
{
    public int Add(int Number1,int Number2)
        {
            return Number1+Number2;
        }
}

如果计算机上的路径与此路径不同,请更改类型库的路径。 要声明要使用的命名空间,请将以下代码添加到CPPClient.cpp文件中:

// Import the type library.
#import "..\ManagedDLL\bin\Debug\ManagedDLL.tlb" raw_interfaces_only

完整的代码清单

using namespace ManagedDLL;

参考: How to call a managed DLL from native Visual C++ code in Visual Studio.NET or in Visual Studio 2005

答案 1 :(得分:1)

或者,我以前做过的事情(在我转而使用P / Invoke方法从C#调用C ++之前)就有3个项目(正如StraightLine所提到的那样)但是我有C#,托管C ++,和Native C ++,让托管C ++成为我的桥梁/代理,在两者之间进行交谈(Native C ++和C#)。这样就更容易在我的Native C ++方面工作。一个警告是一些STL(主要是容器)不受托管支持或有时,std :: string(托管C ++版本)的行为在Native C ++ std :: string中使用会导致异常,所以要注意哪个STL库支持托管C ++。

另外,正如StraightLine所提到的,桥接代码(在我的情况下,Manaaged C ++)必须有一个包装器,它将从Managed编组为Native,反之亦然(即你的" const char *&#34 ;到System.String,如果你的char是8位,等等)

答案 2 :(得分:0)

您必须在程序集中构建相关的C#代码,然后在C ++ CLI项目中引用该程序集。在C ++ CLI包装器中,您将调用通过此C#程序集公开的函数,同时您将调用本机C ++代码。

C ++ CLI项目可以包含本机C ++代码,只需确保没有为本机文件启用CLR开关。那么,你将有3个项目 -

  1. 用于GUI的C#项目将调用main。还引用用于公开C#函数的程序集,以通过C ++ interop调用。
  2. 公开某些托管函数的C#程序集(因此可从C ++ CLI调用)
  3. C ++ CLI项目,它将包装并包含本机代码。