Я пытаюсь настроить тестовый проект, чтобы выяснить, как правильно обернуть нативную C ++ lib в управляемую C ++ DLL, чтобы затем вызывать ее из приложения C #.
Для моего тестового примера у меня есть 3 приложения:
CPP lib
Я компилирую библиотеку с классом, содержащим четыре функции.
1) вернуть двойное значение
2) вернуть строку
3) Возьмите дубль по ссылке, измените его.
4) взять строку по ссылке, изменить ее.
cpp_lib.h
namespace cpp_lib
{
class CPPLibFunctions{
public:
CPPLibFunctions();
public:
static double getValue();
static void incrementValue(double& val);
static std::string getText();
static void changeText(std::string& txt);
};
}
cpp_lib.cpp
#include "cpp_lib.h"
#include <stdexcept>
namespace cpp_lib{
CPPLibFunctions::CPPLibFunctions(){};
double CPPLibFunctions::getValue(){
return 5.5;
}
void CPPLibFunctions::incrementValue(double& val){
val += 1.0;
}
std::string CPPLibFunctions::getText(){
return "success";
}
void CPPLibFunctions::changeText(std::string& txt){
txt += "_123";
}
}
Управляемая библиотека CPP
Это управляемый проект C ++, скомпилированный в DLL, который оборачивает функции из cpp_lib.
managed_cpp_lib.h
#include "cpp_lib.h"
#pragma once
#include <msclr\marshal_cppstd.h>
using namespace System;
namespace managed_cpp_lib {
System::String^ stdToSysString(std::string str){
return gcnew System::String(str.c_str());
}
public ref class ManagedCppFunctions
{
private:
cpp_lib::CPPLibFunctions * cppLibFunctions;
public:
ManagedCppFunctions(){
cppLibFunctions = new cpp_lib::CPPLibFunctions();
}
double getValue(){
return cppLibFunctions->getValue();
}
void incrementValue(double& val){
cppLibFunctions->incrementValue(val);
}
System::String^ getText(){
return stdToSysString(cppLibFunctions->getText());
}
void changeText(System::String^ txt){
//this does not work:
std::string txtstd = msclr::interop::marshal_as<std::string>(txt);
cppLibFunctions->changeText(txtstd);
txt = stdToSysString(txtstd);
}
};
}
csharp_app
Наконец, cssharp_app - это консольное приложение C #, которое ссылается на managed_cpp_lib и вызывает функции.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using managed_cpp_lib;
namespace csharp_app
{
class Program
{
static void Main(string[] args)
{
managed_cpp_lib.ManagedCppFunctions managedCppFunctions = new managed_cpp_lib.ManagedCppFunctions();
//works:
double val = managedCppFunctions.getValue();
Console.WriteLine("\managedCppFunctions.getValue() = {0}", val);
//works:
string txt = managedCppFunctions.getText();
Console.WriteLine("\managedCppFunctions.getText() = {0}", txt);
//does not work:
/*managedCppFunctions.incrementValue(val);
Console.WriteLine("\managedCppFunctions.incrementValue(val) = {0}", val);*/
//the string is not modified:
managedCppFunctions.changeText(txt);
Console.WriteLine("\managedCppFunctions.changeText(txt) = {0}", txt);
Console.WriteLine("...");
}
}
}
Вывод csharp_app :
managedCppFunctions.getValue() = 5.5
managedCppFunctions.getText() = success
managedCppFunctions.changeText(txt) = success
Так managedCppFunctions.getValue()
и managedCppFunctions.getText()
работает.
managedCppFunctions.changeText(txt)
не изменяет содержимое строки.
Я не уверен, как реализовать managedCppFunctions.incrementValue(val)
.
Как правильно передать значение типа double и строку по ссылке, чтобы затем изменить их значения, используя управляемые C ++ и C #?