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
Ashwin took the time to make a sample project and a blog post tutorial which may help further.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…