如何从C#C ++ / CLI中访问类? [英] How to access class in C++/CLI from 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:
- The C++ project and the test code;
- The C++ DLL project which only compiles a DLL out of the first project source using dynamic links;
- The wrapper project which is only an adapter using C++/CLI, which wraps around the raw C++;
- 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.
- Inside Visual Studio, go to File > New > Project, Select Win32 project from the Visual C++ tab.
- Choose a name for both the project and the Solution, the solution will have all the projects inside.
- 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.
- Add a new project (class library in Visual C + +) (called "Wrapper" in this example) to the solution;
- Add the path to the native project with the additional Include directories;
- Add the native project as a reference for the new project (right click-> References ...> Add New Link);
- 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).
- Add the C++/ CLI project as a reference for the new project;
- 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屋!