How to access class in C++/CLI from C#?

浪尽此生 提交于 2019-11-28 06:33:31

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

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

Bartel

For me, the answer to this similar question solved that same error in C#.

(i.e. I had a wrapper header file in my C++\CLI project, but forgot to include a .cpp file as well (even though it only has two lines in it: #include "stdafx.h" and #include "Wrapper.h"))

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!