Visual Studio 2010 — ошибка компоновщика при использовании unique_ptr в C ++ / CLI

В настоящее время я конвертирую свои экземпляры auto_ptr в unique_ptr, но я решаю проблему. Он прекрасно работает в части кода C ++, но при выполнении этого на моем управляемом уровне C ++ / CLI (программное обеспечение использует как C #, так и C ++), я получаю ошибки ссылок. Компилируется нормально, но ломается во время ссылки. Там никогда не было никаких проблем с auto_ptr,

В настоящее время я использую Visual Studio 2010. Кто-нибудь знает какие-либо проблемы с использованием unique_ptr в C ++ / CLI?

Я попытался описать свою проблему в приведенном ниже фрагменте кода, но учтите, что приведенный ниже код на самом деле компилирует и работает (Я проверил, что владение указателями перемещено правильно). Я не получаю ошибки компоновки при компиляции, но код ниже чистый C ++, а не C ++ / CLI. Я просто хотел иметь минимальный пример того, как строится код, чтобы иметь смысл читать ошибки компоновщика.

#include "stdafx.h"#include <vector>
#include <memory>
#include <utility>

using namespace std;

namespace Test {

template< class T >
struct LinAlgPoint3 {
LinAlgPoint3() { x = y = z = 0; };

union {
struct {T x,y,z;} ;
T data_[3];
};
};

class ContainerClass
{
public:
void setUniquePtr(
unique_ptr< vector< LinAlgPoint3< float > > > newUniquePtr1 ,
unique_ptr< vector< unsigned char > > newUniquePtr2 )
{
m_uniquePtr1 = move(newUniquePtr1);
m_uniquePtr2 = move(newUniquePtr2);
}

private:
unique_ptr< vector< LinAlgPoint3< float > > > m_uniquePtr1;
unique_ptr< vector< unsigned char > > m_uniquePtr2;
};

int main(int argc, char** argv)
{
auto pos = unique_ptr< vector< LinAlgPoint3< float > > >( new vector< LinAlgPoint3< float > >() );
auto name = unique_ptr< vector< unsigned char > >(new vector< unsigned char >());
ContainerClass container;
container.setUniquePtr(move(pos), move(name));
}

} //namespace Test

Ошибка, которую я получаю при линковке, следующая:

error LNK2028: unresolved token (0A0018A5) "private: __cdecl std::unique_ptr<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > >,struct std::default_delete<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > > > >::unique_ptr<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > >,struct std::default_delete<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > > > >(class std::unique_ptr<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > >,struct std::default_delete<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > > > > const &)" (??0?$unique_ptr@V?$vector@U?$LinAlgPoint3@M@Test@@V?$allocator@U?$LinAlgPoint3@M@Test@@@std@@@std@@U?$default_delete@V?$vector@U?$LinAlgPoint3@M@Test@@V?$allocator@U?$LinAlgPoint3@M@Test@@@std@@@std@@@2@@std@@$$FAEAA@AEBV01@@Z) referenced in function "public: static void __clrcall std::unique_ptr<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > >,struct std::default_delete<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > > > >::<MarshalCopy>(class std::unique_ptr<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > >,struct std::default_delete<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > > > > *,class std::unique_ptr<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > >,struct std::default_delete<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > > > > *)" (?<MarshalCopy>@?$unique_ptr@V?$vector@U?$LinAlgPoint3@M@Test@@V?$allocator@U?$LinAlgPoint3@M@Test@@@std@@@std@@U?$default_delete@V?$vector@U?$LinAlgPoint3@M@Test@@V?$allocator@U?$LinAlgPoint3@M@Test@@@std@@@std@@@2@@std@@$$FSMXPEAV12@0@Z)
1>TestClass.obj : error LNK2028: unresolved token (0A0018A6) "private: __cdecl std::unique_ptr<class std::vector<unsigned char,class std::allocator<unsigned char> >,struct std::default_delete<class std::vector<unsigned char,class std::allocator<unsigned char> > > >::unique_ptr<class std::vector<unsigned char,class std::allocator<unsigned char> >,struct std::default_delete<class std::vector<unsigned char,class std::allocator<unsigned char> > > >(class std::unique_ptr<class std::vector<unsigned char,class std::allocator<unsigned char> >,struct std::default_delete<class std::vector<unsigned char,class std::allocator<unsigned char> > > > const &)" (??0?$unique_ptr@V?$vector@EV?$allocator@E@std@@@std@@U?$default_delete@V?$vector@EV?$allocator@E@std@@@std@@@2@@std@@$$FAEAA@AEBV01@@Z) referenced in function "public: static void __clrcall std::unique_ptr<class std::vector<unsigned char,class std::allocator<unsigned char> >,struct std::default_delete<class std::vector<unsigned char,class std::allocator<unsigned char> > > >::<MarshalCopy>(class std::unique_ptr<class std::vector<unsigned char,class std::allocator<unsigned char> >,struct std::default_delete<class std::vector<unsigned char,class std::allocator<unsigned char> > > > *,class std::unique_ptr<class std::vector<unsigned char,class std::allocator<unsigned char> >,struct std::default_delete<class std::vector<unsigned char,class std::allocator<unsigned char> > > > *)" (?<MarshalCopy>@?$unique_ptr@V?$vector@EV?$allocator@E@std@@@std@@U?$default_delete@V?$vector@EV?$allocator@E@std@@@std@@@2@@std@@$$FSMXPEAV12@0@Z)
1>TestClass.obj : error LNK2019: unresolved external symbol "private: __cdecl std::unique_ptr<class std::vector<unsigned char,class std::allocator<unsigned char> >,struct std::default_delete<class std::vector<unsigned char,class std::allocator<unsigned char> > > >::unique_ptr<class std::vector<unsigned char,class std::allocator<unsigned char> >,struct std::default_delete<class std::vector<unsigned char,class std::allocator<unsigned char> > > >(class std::unique_ptr<class std::vector<unsigned char,class std::allocator<unsigned char> >,struct std::default_delete<class std::vector<unsigned char,class std::allocator<unsigned char> > > > const &)" (??0?$unique_ptr@V?$vector@EV?$allocator@E@std@@@std@@U?$default_delete@V?$vector@EV?$allocator@E@std@@@std@@@2@@std@@$$FAEAA@AEBV01@@Z) referenced in function "public: static void __clrcall std::unique_ptr<class std::vector<unsigned char,class std::allocator<unsigned char> >,struct std::default_delete<class std::vector<unsigned char,class std::allocator<unsigned char> > > >::<MarshalCopy>(class std::unique_ptr<class std::vector<unsigned char,class std::allocator<unsigned char> >,struct std::default_delete<class std::vector<unsigned char,class std::allocator<unsigned char> > > > *,class std::unique_ptr<class std::vector<unsigned char,class std::allocator<unsigned char> >,struct std::default_delete<class std::vector<unsigned char,class std::allocator<unsigned char> > > > *)" (?<MarshalCopy>@?$unique_ptr@V?$vector@EV?$allocator@E@std@@@std@@U?$default_delete@V?$vector@EV?$allocator@E@std@@@std@@@2@@std@@$$FSMXPEAV12@0@Z)
1>TestClass.obj : error LNK2019: unresolved external symbol "private: __cdecl std::unique_ptr<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > >,struct std::default_delete<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > > > >::unique_ptr<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > >,struct std::default_delete<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > > > >(class std::unique_ptr<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > >,struct std::default_delete<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > > > > const &)" (??0?$unique_ptr@V?$vector@U?$LinAlgPoint3@M@Test@@V?$allocator@U?$LinAlgPoint3@M@Test@@@std@@@std@@U?$default_delete@V?$vector@U?$LinAlgPoint3@M@Test@@V?$allocator@U?$LinAlgPoint3@M@Test@@@std@@@std@@@2@@std@@$$FAEAA@AEBV01@@Z) referenced in function "public: static void __clrcall std::unique_ptr<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > >,struct std::default_delete<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > > > >::<MarshalCopy>(class std::unique_ptr<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > >,struct std::default_delete<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > > > > *,class std::unique_ptr<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > >,struct std::default_delete<class std::vector<struct LinAlgPoint3<float>,class std::allocator<struct LinAlgPoint3<float> > > > > *)" (?<MarshalCopy>@?$unique_ptr@V?$vector@U?$LinAlgPoint3@M@Test@@V?$allocator@U?$LinAlgPoint3@M@Test@@@std@@@std@@U?$default_delete@V?$vector@U?$LinAlgPoint3@M@Test@@V?$allocator@U?$LinAlgPoint3@M@Test@@@std@@@std@@@2@@std@@$$FSMXPEAV12@0@Z)
1>D:\Test\Test.dll : fatal error LNK1120: 4 unresolved externals

Как вы можете видеть (если вы можете пройти через невероятно ужасные сообщения), есть некоторые ссылки на MarshalCopy, что заставляет меня беспокоиться о том, что C ++ / CLI может еще не поддерживать unique_ptr.

Макет программного обеспечения

C# executable -> C++/CLI translation layer (dll) -> C++ dll

Таким образом, C ++ dll компилируется нормально с использованием unique_ptr, но C ++ / CLI dll не может правильно связать.

Я забыл упомянуть кое-что очень важное: если я использую unique_ptr для более простого типа данных, например строки, он успешно связывается. Например:

  auto string1= unique_ptr< string >(new string(20000, 'S'));
auto string2 = unique_ptr< string >(new string(20000, 'A'));
string1= std::move(string2);

и я также попытался использовать переменную, чтобы компилятор не оптимизировал ее.

Редактировать: Я только что протестировал добавление еще одной внешней функции, которая принимает unique_ptr<string>, и я попытался отправить в выше string1 и это тоже ломается! Таким образом, проблема должна быть между сгенерированными DLL, так как std :: move () хорошо работает в каждом файле / классе.

7

Решение

Ну, не знаю, насколько это актуально сейчас, но у меня была точно такая же проблема с C ++ / CLI, и я решил ее, приняв ссылку на r-значение вместо значения. Я имею в виду:
void setUniquePtr (unique_ptr&& a, unique_ptr&& б)

Таким образом, он компилируется, хотя это не самый чистый способ делать вещи.

8

Другие решения

Читая это сложное сообщение об ошибке, я думаю, что это жалуется, что LinAlgPoint3 Структура не имеет конструктора копирования. Попробуйте реализовать конструктор копирования, и, возможно, операторы = а также ==и посмотрим, исправит ли это.

2

Вы не можете передавать объекты C ++ между DLL и ожидать, что они будут работать правильно.

Расположение памяти может быть разным в разных модулях. Почти наверняка используются разные распределители (это сбивает любой тип C ++, который владеет памятью, включая string, vector, а также unique_ptr).

В этом может помочь использование указателей на чисто виртуальные базовые классы.

Или, если у вас есть исходный код для части C ++, попробуйте связать C ++ и C ++ / CLI в одну DLL, а не ссылаться на код C ++ в отдельной DLL.

1
По вопросам рекламы [email protected]