C++/CLI 混合托管/本机 DLL 不起作用

C++/CLI mixed managed/native DLL won't work

本文关键字:本机 DLL 不起作用 CLI 混合 C++      更新时间:2023-10-16

我正在创建一个C++/CLI 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++ 
}

其余的已经在上面说明过了。

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

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

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

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

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

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