我正在尝试建立一个测试项目,以弄清楚如何将本地C ++库正确包装在托管C ++ DLL中,然后由C#应用程序调用。
对于我的测试用例,我有3个应用程序:
CPP库
我用一个包含四个函数的类编译一个库。
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库
这是一个编译为DLL的托管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)
。
通过引用传递双精度和字符串,然后使用托管C ++和C#更改其值的正确方法是什么?