C ++ / CLI混合托管/本机DLL无法正常工作

时间:2018-09-20 07:57:32

标签: c# c++ c++-cli command-line-interface clr

我正在创建一个C ++ / CLI DLL,该DLL应该用作包装器。它的目的是包装C#SDK并将函数呈现给本机C ++代码。 我总是会得到混合类型的错误,并且托管类中的using语句被标记为红色,所以到目前为止,这是我得到的:

#pragma once

#include <iostream>
#include <memory>
#include <string>

namespace TPInterface
{
class ITPFactory
{
public:
  static __declspec(dllexport) std::shared_ptr<ITPFactory> CreateTPFactory();
};
}

哪个将创建TPFactory的实例。

#pragma once

#include "ITPSSITotalStation.h"
#include "TPSSITotalStation.h"
#include "ITPFactory.h"
#include <iostream>
#include <memory>
#include <string>

namespace TPInterface
{
class TPFactory : public ITPFactory
{
public:
  static std::shared_ptr<SensorSoftwareInterface::TotalStation::ITPSSITotalStation> CreateTPSSITotalStation(std::string pathToDriver);
};
}

这将创建一个TPSSITotalStation对象,它是ITPSSITotalStation接口。

TPSSITotalStation-> TPSSIBase-> TPBase

TPSSIBaseTPBase都包含用托管代码编写的类(gcroot和标头)(ref类)。

现在,编译器告诉我,那些ref类是混合的,不允许的,依此类推。我在这里没问题...我在做什么错了?

很抱歉,我是C ++的新手,来自C#。

错误:

Error   7   error C4368: cannot define 'm_selectedPath' as a member of managed 'TPInterface::Driver': mixed types are not supported

Error   8   error C4368: cannot define 'm_assemblyNameAndVersion' as a member of managed 'TPInterface::Driver': mixed types are not supported   

Error   9   error C2678: binary '=' : no operator found which takes a left-hand operand of type 'std::string' (or there is no acceptable conversion)    

Error   28  error C3265: cannot declare a managed '_Ptr' in an unmanaged 'std::tr1::_Ptr_base<_Ty>'

Error   51  error C3699: '*' : cannot use this indirection on type 'TPInterface::Sensor'    

Error   65  error C3642: 'TPInterface::Sensor msclr::gcroot<T>::operator ->(void) const' : cannot call a function with __clrcall calling convention from native code

用于理解目的的小示例:

ref class Driver // Contains errors in using (C#) statements
{
  // Does something managed
    private:
  std::string m_selectedPath;
  std::string m_assemblyNameAndVersion;
}
ref class Sensor // Contains errors in using (C#) statements
{
  // Does something managed
}

class TPBase
{
  // includes Driver class and holds it also inside msclr::gcroot<Driver^> 
}
class TPSSIBase : TPBase
{
  // includes Sensor and Driver class and holds sensor also inside msclr::gcroot<Sensor^> 
}
class TPSSITotalStation : TPSSIBase, public ITPSSITotalStation
{
  // contains functions which should be exported to native C++ 
}

其余内容已在上面说明。

2 个答案:

答案 0 :(得分:4)

  1. 您不能从托管类派生非托管类。
  2. 您不能从非托管类派生托管类。
  3. 您不能将托管成员添加到非托管类中
  4. 您不能将非托管数据成员(指针除外)添加到托管类。
  5. 在非托管类中,您可以编写返回托管类型的函数。
  6. 在托管类中,您只能形成使用允许的托管类型的函数。

该怎么做,创建一个包装器:

  1. 为需要创建和保存的所有托管对象创建一个包含gcroot<..>指针/对象的非托管类。查看gcroot<..>模板的文档。
  2. 在托管类中,您可以自由保存指向非托管世界的指针。

只要使用gcroot和普通指针,就可以轻松地从非托管世界访问.NET世界,反之亦然。

答案 1 :(得分:2)

由于std::string是非托管类型,但是ref class Driver是托管类,因此无法在托管类中定义具有非托管类型的字段。

如果要定义字符串字段,请改用System.String^