Ошибки реализации оболочки C ++ / CLI - PullRequest
0 голосов
/ 25 марта 2020

Я пытался использовать схему оболочки C ++ / CLI по следующей ссылке.

Примечание: во всех поисках, которые я выполнял за последнюю неделю, нижеприведенный проект является наиболее цитируемым как обеспечивающее работоспособное решение.
http://pragmateek.com/using-c-from-native-c-with-the-help-of-ccli-v2/

Данный проект является моей попыткой создать ссылку на стороннее приложение, которое принимает Win32 Dll. Hy цель состоит в том, чтобы связать Win32 Dll с управляемой C# DLL, где функции должны быть проще для написания и поддержки.

Однако я продолжаю сталкиваться с вариантами следующих ошибок.

Error   C2664   'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(std::initializer_list<_Elem>,const std::allocator<char> &)' : cannot convert argument 1 from 'System::String ^' to 'const std::basic_string<char,std::char_traits<char>,std::allocator<char>> &' Main_interface  

Error (active)  E0415   no suitable constructor exists to convert from "System::String ^" to "std::basic_string<char, std::char_traits<char>, std::allocator<char>>"    Main_interface  

Моя C# Библиотека: MainUtilities.dll

//Main_Utility.cs

public class MainUtilities
{
    public string GetRevision(string CurrentRev)
    {
        return CurrentRev + "_rev";
    }
}

Main_Interface.h

#pragma once

#define DLL_EXP extern "C" __declspec(dllexport)
DLL_EXP void GetRevision(char* data_in, char *data_out);

class QFUtilitiesWrapperPrivate;

#ifdef BUILDINGQFUTILITIES
#define DLL_EXP_WRAP __declspec(dllexport)
#else
#define DLL_EXP_WRAP __declspec(dllimport)
#endif

#include <string>

class DLL_EXP_WRAP QF_UtilitiesWrapper
{
private: static QFUtilitiesWrapperPrivate* _private;

public: QF_UtilitiesWrapper();

public: ~QF_UtilitiesWrapper();

public: static std::string GetRevisionFunc(const char* rev);

};

Main_Interface. cpp

#include "stdafx.h"
#include "Main_Interface.h"
#include <msclr\auto_gcroot.h>
#using "MainUtilities.dll"
using namespace System::Runtime::InteropServices; // Marshal


class QFUtilitiesWrapperPrivate
{
public: msclr::auto_gcroot<MainUtilities^> main_Utilities;
};

QF_UtilitiesWrapper::QF_UtilitiesWrapper()
{
    _private = new QFUtilitiesWrapperPrivate();
    _private->main_Utilities = gcnew MainUtilities();
}

DLL_EXP void GetRevision(char* data_in, char *data_out)
{
    std::string s_b = QF_UtilitiesWrapper::GetRevisionFunc(data_in);
    strcpy_s(data_out, 100, s_b.c_str());
}

std::string QF_UtilitiesWrapper::GetRevisionFunc(const char* data_in)
{
    return _private->main_Utilities->GetRevision(gcnew System::String(data_in));
} //** ERROR ^^^^^^  ** 

QF_UtilitiesWrapper::~QF_UtilitiesWrapper()
{
    delete _private;
}

Обратите внимание на ошибки происходят по адресу: 'GetRevisionFun c'


РЕДАКТИРОВАТЬ: ОК. Я внес следующие изменения:

//Main_Interface.h

private:  QFUtilitiesWrapperPrivate* _private;  // no longer static
public: const char* GetRevisionFunc(const char* rev); //function now: const char*
//Main_Interface.cpp

DLL_EXP void GetRevision(char* data_in, char *data_out)
{
    data_out = QF_UtilitiesWrapper::GetRevisionFunc(data_in);
  // ** ERROR ^^^^^^^^^^ **
}

const char* QF_UtilitiesWrapper::GetRevisionFunc( char* rev) // now: const char*
{
    System::String^ managedCapi = _private->main_Utilities->GetRevision(gcnew System::String(rev));
    return (const char*)Marshal::StringToHGlobalAnsi(managedCapi).ToPointer();
}

Теперь я привязываюсь к устранить следующие ошибки:

Error C2352 'QF_UtilitiesWrapper::GetRevisionFunc' : illegal call of non-static member function

Error (active) E0245 a nonstatic member reference must be relative to a specific object

1 Ответ

1 голос
/ 25 марта 2020

Ну, вы должны маршалировать типы, это не сделано для вас в C ++ / CLI. У вас есть System::String^, но вы хотите вернуть его как std::string, поэтому вам необходимо упорядочить его:

std::string QF_UtilitiesWrapper::GetRevisionFunc(const char* data_in)
{
    auto str = _private->main_Utilities->GetRevision(gcnew System::String(data_in));
    return msclr::interop::marshal_as<std::string>(str);
}

Для получения более подробной информации оформите документы .

Также ваш QF_UtilitiesWrapper содержит _private как stati c член, и вы устанавливаете и удаляете его в своем конструкторе / деструкторе. Это приведет к утечке памяти и, возможно, к непредвиденному поведению.

...