通过引用从C#传递值来调用托管C ++库

时间:2018-07-06 07:38:01

标签: c# c++ managed-c++

我正在尝试建立一个测试项目,以弄清楚如何将本地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#更改其值的正确方法是什么?

0 个答案:

没有答案