Actualmente estoy convirtiendo mis instancias de auto_ptr
a unique_ptr
, pero estoy solucionando un problema. Funciona muy bien en la parte C++ del código, pero cuando lo hago en mi capa administrada C++/CLI (el software usa C# y C++) obtengo errores de enlace. Se compila bien, pero se rompe en el momento del enlace. Nunca hubo problemas con auto_ptr
.Error de vinculador cuando se utiliza unique_ptr en C++/CLI
Actualmente estoy usando Visual Studio 2010. ¿Alguien sabe de algún problema con el uso de unique_ptr
en C++/CLI?
He tratado de resumir mi problema en un fragmento de código a continuación, pero tenga en cuenta que el código de en realidad compila y funciona (he comprobado que la propiedad de los punteros se mueve correctamente). No obtengo errores de enlace al compilar esto, pero el código siguiente es puro C++ y no C++/CLI. Solo quería tener un ejemplo mínimo de cómo se construye el código, por lo que el error del enlazador tiene más sentido para leer.
#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
El error que consigo cuando se vincula es la siguiente:
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 &)" ([email protected][email protected][email protected]@[email protected]@[email protected][email protected]@[email protected]@@[email protected]@@[email protected]@[email protected][email protected][email protected]@[email protected]@[email protected][email protected]@[email protected]@@[email protected]@@[email protected]@@[email protected]@[email protected]@[email protected]@@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>@[email protected][email protected][email protected]@[email protected]@[email protected][email protected]@[email protected]@@[email protected]@@[email protected]@[email protected][email protected][email protected]@[email protected]@[email protected][email protected]@[email protected]@@[email protected]@@[email protected]@@[email protected]@[email protected]@[email protected]@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 &)" ([email protected][email protected][email protected]@[email protected]@@[email protected]@[email protected][email protected][email protected]@[email protected]@@[email protected]@@[email protected]@[email protected]@[email protected]@@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>@[email protected][email protected][email protected]@[email protected]@@[email protected]@[email protected][email protected][email protected]@[email protected]@@[email protected]@@[email protected]@[email protected]@[email protected]@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 &)" ([email protected][email protected][email protected]@[email protected]@@[email protected]@[email protected][email protected][email protected]@[email protected]@@[email protected]@@[email protected]@[email protected]@[email protected]@@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>@[email protected][email protected][email protected]@[email protected]@@[email protected]@[email protected][email protected][email protected]@[email protected]@@[email protected]@@[email protected]@[email protected]@[email protected]@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 &)" ([email protected][email protected][email protected]@[email protected]@[email protected][email protected]@[email protected]@@[email protected]@@[email protected]@[email protected][email protected][email protected]@[email protected]@[email protected][email protected]@[email protected]@@[email protected]@@[email protected]@@[email protected]@[email protected]@[email protected]@@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>@[email protected][email protected][email protected]@[email protected]@[email protected][email protected]@[email protected]@@[email protected]@@[email protected]@[email protected][email protected][email protected]@[email protected]@[email protected][email protected]@[email protected]@@[email protected]@@[email protected]@@[email protected]@[email protected]@[email protected]@Z)
1>D:\Test\Test.dll : fatal error LNK1120: 4 unresolved externals
Como se puede ver (si se puede conseguir a través de los mensajes increíblemente horrible) hay algunas referencias a MarshalCopy, algo que me hace Preocuparse de que C++/CLI aún no sea compatible con unique_ptr.
El diseño del software es
C# executable -> C++/CLI translation layer (dll) -> C++ dll
Así que la DLL C++ compila bien utilizando unique_ptr, pero el DLL C++/CLI es incapaz de enlazar correctamente.
Olvidé mencionar algo bastante importante: si uso unique_ptr para un tipo de datos más simple, por ejemplo una cadena, se vincula con éxito. Por ejemplo:
auto string1= unique_ptr<string>(new string(20000, 'S'));
auto string2 = unique_ptr<string>(new string(20000, 'A'));
string1= std::move(string2);
y también he intentado asegurarme de usar la variable para que el compilador no la optimice.
Editar: he probado simplemente añadiendo otra función externa que acepta un unique_ptr<string>
, y yo probamos el envío de lo anterior string1
y que rompe así! Entonces, el problema debe ser entre las DLL generadas, ya que std :: move() funciona bien dentro de cada archivo/clase.
Es difícil diagnosticar un problema cuando solo vemos los errores, no el código que los creó. Dijiste que este código C++ funciona, pero tu código C++/CLI real no. ¿Puedes escribir algún código de C++/CLI que muestre el problema? –
Puedo intentar ... No escribí mucho C++/CLI desde cero en mis días :) – AzP
Comente todas las llamadas de movimiento para obtener una compilación limpia. La semántica de movimiento es una característica de C++ 11 implementada por el compilador de C++. No por el compilador C++/CLI. Podría publicar en connect.microsoft.com para sacudir ese árbol. –