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

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

问题描述

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



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



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



C ++ / CLI项目中的原始C标题

  #define ABC 0x12345 

C ++ / CLI项目中的包装器类

  #includemy_c_header.h

命名空间C_Wrappers {
public ref class MyWrapper {
public:
属性unsigned int C_ABC {
unsigned int get(){return ABC;
}
}
}

C#项目中的用户类

 使用C_Wrappers; 
使用系统;

命名空间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指令或程序集引用?)



我以为我做了我应该做的一切。我应该如何解决这个错误?

解决方案

我发现花时间制作一个示例项目和一个博客文章教程,这可能有助于进一步。


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) 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) I ran into a reference problem. Here's my simplified code to illustrate the problem:

Original C header in C++/CLI project

#define ABC  0x12345

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

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?

解决方案

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.

In my own solution, I had 4 projects:

  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.

The C++ DLL project

Make your C++ code into a DLL lib.

  1. Inside Visual Studio, go to File > New > Project, Select Win32 project from the Visual C++ tab.
  2. Choose a name for both the project and the Solution, the solution will have all the projects inside.
  3. Inside the assistant for Win32 Application, click next, check the "DLL" box, then "Empty project" then click finish.

Code to add

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();

There's nothing to change inside the CPP.

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

The C++/CLI wrapper

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

  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

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

Nothing special inside the CPP except that you have to include #include "stdafx.h".

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

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

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. Add the C++/ CLI project as a reference for the new project;
  2. Add Directive using Wrapper; in source code form;

Use it like:

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

Update 2016/05/06

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

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

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