如何从C#访问类C ++ / CLI? [英] How to access class in C++/CLI from C#?

查看:277
本文介绍了如何从C#访问类C ++ / CLI?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写在C#中的GUI工具来解析和显示用C写的。为了解析我需要知道这是在一些C头文件中指定的数据结构中的数据另一个程序的数据输出。因此,我需要将这些C头文件纳入我的C#项目。我的问题是:

I am writing a GUI tool in C# to parse and display the data output of another program written in C. In order to parse the data I need to know the data structures which are specified in a number of C header files. Thus I need to incorporate those C header files into my C# project. My questions are:

1)一些研究,我得出的结论是最好的办法是在我的解决方案来创建一个新的C ++ / CLI项目,导入C头文件这个新的项目,写一些充当薄包装在C头文件中定义的数据结构,C ++ / CLI类,然后从C#代码引用C ++ / CLI的包装类。这是最好的办法,还是有更好的办法?

1) After some research I came to conclude that the best way is to create a new C++/CLI project in my solution, import the C header files into this new project, write some C++/CLI classes that act as thin wrappers for the data structures defined in the C header files, then reference the C++/CLI wrapper classes from the C# code. Is this the best approach, or is there a better way?

2),我遇到了一个参考的问题。这里是我的简单的代码来说明这个问题:

2) I ran into a reference problem. Here's my simplified code to illustrate the problem:

在C ++ / CLI项目原来的C头文件

Original C header in C++/CLI project

#define ABC  0x12345

包装在C ++ / CLI项目类

Wrapper class in C++/CLI project

#include "my_c_header.h"

namespace C_Wrappers {
    public ref class MyWrapper {
        public:
            property unsigned int C_ABC {
                unsigned int get() { return ABC; }
            }
    }
 }



User类在C#项目

User class in C# project

using C_Wrappers;
using System;

namespace DataViewer {
    public partial class MainForm : Form {
        private  MyWrapper myWrapper = new MyWrapper();
        public MainForm() {
            Console.WriteLine(myWrapper.C_ABC.ToString());
        }
    }
 }

在我添加了C#项目在C ++ / CLI项目的引用(使用鼠标右键>添加引用)。在生成过程中我得到了在C#项目中的错误:类型或命名空间C_Wrappers'找不到(是否缺少using指令或程序集引用)

In the C# project I added a reference to the C++/CLI project (using right click > Add Reference). During build I got an error in the C# project: "The type or namespace 'C_Wrappers' could not be found (are you missing a using directive or an assembly reference?)."

我认为我做的一切都是我应该。我应该怎么做来解决这个问题?

I thought I did everything I was supposed to. What should I do to fix this error?

推荐答案

我发现的这个链接的时候,我需要用WPF链接C ++到C#的令人难以置信的是有用的。 。不幸的是,它是用法语写的,所以我联系谷歌提供的翻译版本

I found this link unbelievably useful when I needed to link C++ to C# with WPF. Unfortunatly, it is written in french, so I linked the translated version provided by google.

在我自己的解决方案,我有4个项目:

In my own solution, I had 4 projects:


  1. C ++的项目和测试代码;

  2. 的C ++ DLL项目,该项目只使用编译一个DLL出的第一个项目源动态链接;

  3. 的包装项目,该项目仅使用C ++ / CLI,它周围的原始C ++封装了一个适配器;

  4. C#的WPF项目,该项目是我的图形界面。

  1. The C++ project and the test code;
  2. The C++ DLL project which only compiles a DLL out of the first project source using dynamic links;
  3. The wrapper project which is only an adapter using C++/CLI, which wraps around the raw C++;
  4. The C# WPF project which was my graphical interface.

下面是我上面提供的链接的翻译。

Here's my translation of the provided link above.

请你的C ++代码放到一个DLL库。

Make your C++ code into a DLL lib.


  1. 在Visual Studio中,转到文件>新建>项目,从Visual C选择的Win32项目++选项卡。

  2. 选择项目和解决方案都具有一个名称,该解决方案将所有里面的项目。

  3. 助理为Win32应用程序中,点击下一步,选中DLL框,然后选择空项目,然后点击完成。


这是我的C ++的DLL头(减去很多的东西)。

This is my C++ header for the dll (minus lot of stuff).

Token.h

#pragma once
#define DLLEXP   __declspec( dllexport )

DLLEXP void pop_back(std::string& str);

DLLEXP std::string testReturnString();

DLLEXP int getRandomNumber();

有什么的CPP内改变。

There's nothing to change inside the CPP.

生成项目,你应该有一个DLL和LIB文件中的C#项目的调试目录包括

Build the project, you should have a DLL and a LIB file to include in the C# project debug dir.

本项目作为从以前的项目中的本地代码之间的接口,以及管理的GUI代码。

This project serves as an interface between the native code from the previous project, and managed code of the GUI.


  1. 添加一个新的项目(类库在Visual C + +)(称为在这个例子中包装)的解决方案;

  2. 添加路径到本地项目与附加包含目录;

  3. 添加本地项目作为新项目(右键点击 - >引用...>添加新的链接)的参考;

  4. 在属性 - >链接器 - >输入,DLL中的延迟加载把名字本地的dll(Computations.dll在这个例子中)字段

  1. Add a new project (class library in Visual C + +) (called "Wrapper" in this example) to the solution;
  2. Add the path to the native project with the additional Include directories;
  3. Add the native project as a reference for the new project (right click-> References ...> Add New Link);
  4. In Properties -> Linker -> Input, put the name of the native dll in the delayed loading of DLLs (Computations.dll in this example) field

我的包装仅仅是一个类,它看起来是这样的(负我自己的代码)。

The C++/CLI code

My wrapper is only a class which looks something like this (minus my own code).

Wrapper.h

Wrapper.h

#include "Token.h" // include your C++ header

#include <string>
#include <iostream>

namespace Wrapper {

    // noticed the ref?
    public ref class TokenAnalyzer
    {

    public:
        TokenAnalyzer(){
        };

        void Init();
            // use the C++/CLI type, like String^ (handles)
        System::String^ ProcessLine(int lineNbr, System::String^ line);
    };
}



没有CPP的内部特殊的不同之处在于你必须包括的#includestdafx.h中

还应该建立成一个DLL,您将包括C#调试目录内。

It should also builds into a DLL which you will include inside the C# debug dir.

只是一个有用的功能,我发现某处左右,但不记得在哪里,你可能需要。它转换成C ++ / CLI字符串处理成一个C ++标准字符串。

Just a useful function I found somewhere on SO but don't remember where that you might need. It convert C++/CLI String handle into a C++ standard string.

std::string MarshalString (String ^ s) {
        using namespace Runtime::InteropServices;
        const char* chars = 
            (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
        std::string os = chars;
        Marshal::FreeHGlobal(IntPtr((void*)chars));
        return os;
    }



的C#项目



添加到解决方案一个新的项目(C#Windows窗体或WPF或任何你想要的!),并将其设置为启动项目(右击 - >设置为启动项目)。

The C# project

Add to the solution a new project (C # Windows Form or WPF or whatever you want!) and set it as the startup project (right-click -> set as startup project).


  1. 添加了C ++ / CLI项目作为新项目的参考;

  2. 添加指令使用包装; 以源代码形式;

  1. Add the C++/ CLI project as a reference for the new project;
  2. Add Directive using Wrapper; in source code form;

使用它像:

/// Store the C++/CLI Wrapper object.</summary>
private Wrapper.TokenAnalyzer mTokenAnalyzer = new TokenAnalyzer();



更新2016年5月6日

Neowin网站花时间做一个样本项目和的博客文章教程这可能进一步帮助。

NeoWin took the time to make a sample project and a blog post tutorial which may help further.

这篇关于如何从C#访问类C ++ / CLI?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆