2012-02-08 28 views
6

Tôi đang tìm một ví dụ (làm việc) để tuần tự bên ngoài một cấu trúc lớp trong một DLL. Hiện tại tôi không thể tìm thấy bất kỳ ví dụ nào về điều đó. Tài liệu Boost chỉ nói một số macro, các diễn đàn và nhóm tin tức chỉ thảo luận các vấn đề cụ thể với các giải pháp của họ.Đặt serialization của một lớp vào một DLL

Vì vậy, tôi yêu cầu một ví dụ về (bên ngoài) tuần tự hóa cấu trúc lớp như sau. Cùng với mã lớp tôi đã thêm một số mã của tôi để tuần tự hóa (không hoạt động, xem phần dưới cùng của thông báo lỗi).

class Foo 
{ 
public: 
    Foo() { number_ = 0; } 
    virtual ~Foo() {} 

    int getNumber() { return number_; } 
    void setNumber(int var) { number_ = var; } 
private: 
    int number_; 
}; 

class Bar : public Foo 
{ 
public: 
    Bar() { doubleNumber_ = 0.0; } 
    virtual ~Bar() {} 

    double getDouble() { return doubleNumber_; } 
    void setDouble(double var) { doubleNumber_ = var; } 

private: 
    double doubleNumber_; 
}; 

Tất cả những gì tôi đã có cho đến nay mã như thế này là:

serializeFoo.h

#ifndef _SERIALIZE_FOO_H_ 
#define _SERIALIZE_FOO_H_ 

#include "Foo.h" 
#include <boost/serialization/split_free.hpp> 
#include <boost/serialization/version.hpp> 

namespace boost { 
namespace serialization { 

template <typename Archive> 
void save(Archive& ar, const Foo& object, const unsigned int version) 
{ 
    ar << object.getNumber(); 
} 

template <typename Archive> 
void load(Archive& ar, Foo& object, const unsigned int version) 
{ 
    int number; 
    ar >> number; 
    object.setNumber(number); 
} 

}} //namespace brackets 

BOOST_SERIALIZATION_SPLIT_FREE(Foo) 

#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 
#include <boost/serialization/export.hpp> 
BOOST_CLASS_EXPORT_KEY(Foo) 

#endif //_SERIALIZE_FOO_H_ 

serializeFoo.cpp

#include "serializeFoo.h" 
BOOST_CLASS_EXPORT_IMPLEMENT(Foo) 

seriali zeBar.h:

#ifndef _SERIALIZE_BAR_H_ 
#define _SERIALIZE_BAR_H_ 

#include "Bar.h" 
#include <boost/serialization/split_free.hpp> 
#include <boost/serialization/version.hpp> 

namespace boost { 
namespace serialization { 

template <typename Archive> 
void save(Archive& ar, const Bar& object, const unsigned int version) 
{ 
    ar << base_object<Foo>(object); 
    ar << object.getDouble(); 
} 

template <typename Archive> 
void load(Archive& ar, Bar& object, const unsigned int version) 
{ 
    double doubleNumber; 
    ar >> doubleNumber; 
    object.setDouble(doubleNumber); 
} 

}} //namespace brackets 

BOOST_SERIALIZATION_SPLIT_FREE(Bar) 

#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 
#include <boost/serialization/export.hpp> 
BOOST_CLASS_EXPORT_KEY(Bar) 

#endif //_SERIALIZE_BAR_H_ 

serializeBar.cpp:

#include "serializeBar.h" 
BOOST_CLASS_EXPORT_IMPLEMENT(Bar) 

Các serialization mã đi vào một DLL và cần được sử dụng trong một dự án khác sử dụng các lớp Foo và Bar. Mọi thứ đều biên soạn tốt, nhưng trong thời gian chạy, tôi nhận được thông báo
unregistered class - derived class not registered or exported

Vì vậy, tôi đã sử dụng các macro sai? Tôi có bỏ lỡ một macro không? Mã trên có đúng hay có lỗi nào đó về cấu trúc? Có lẽ điều này có thể hữu ích cho rất nhiều người khác nữa, tôi không nghĩ rằng việc đưa serialization của một lớp vào một DLL là rất kỳ lạ ...

+0

Điều tôi thấy trên Boost-tài liệu là 'BOOST_SERIALIZATION_FACTORY_0 (Foo)', nhưng tôi không biết nếu nó là cần thiết và nếu tôi nên sử dụng nó. Link: http://www.boost.org/doc/libs/1_37_0/libs/serialization/doc/special.html#dlls – MOnsDaR

+0

Vâng, nếu nó làm cho bạn cảm thấy tốt hơn, tôi có một dự án mà nó hoạt động tốt và mã trông khá giống với những gì bạn có, ngoại trừ thực tế là tôi bao gồm các tiêu đề lưu trữ ở đầu tệp tiêu đề. P.S. Về mặt kỹ thuật, đó là '.so', không phải là một' .dll', không nên tạo sự khác biệt ... – TC1

+0

Bạn nói đúng, tôi có nghĩa là viết "lib chia sẻ" lúc đầu, nhưng đã viết DLL vì tôi muốn hiển thị rằng nó hiện là một vấn đề với loại lib chia sẻ cụ thể này. – MOnsDaR

Trả lời

1

Tôi chạy vào một vấn đề tương tự gần đây, 3 năm sau khi câu hỏi này được hỏi. Cuối cùng tôi đã tìm ra một giải pháp để giải quyết nó. Trong ví dụ trên.

  • Bar là lớp con của Foo, vì vậy phải được đăng ký/xuất;
  • serializeFoo.cpp khởi tạo lớp mẫu GUID để đăng ký/xuất Foo;
  • serializeBar.cpp khởi tạo lớp mẫu GUID để đăng ký/xuất Bar;
  • Quy tắc bao gồm tất cả các loại lưu trữ cần thiết trước khi xuất khẩu khóa học được tôn trọng;
  • Cả hai đơn vị dịch đều được liên kết với nhau để tạo DLL.

tôi giả sử trong exe của bạn, trong khi bạn đang cố gắng để serialise một con trỏ Foo* trỏ đến một đối tượng Bar, bạn đã nhận lỗi "không đăng ký lớp blahblah". Điều này là do Boost.Serialization bằng cách nào đó không đúng cách tạo ra một GUID cho lớp Bartrước khi chức năng tuần tự được gọi.

Tôi không biết tại sao điều này xảy ra, nhưng dường như GUID được tạo theo cách lười biếng - nếu không có ký hiệu nào trong đơn vị dịch serializeBar.cpp được sử dụng, không có mã khởi tạo/khởi tạo nào được xác định trong bản dịch đó đơn vị sẽ được thực hiện - bao gồm đăng ký/xuất khẩu lớp Bar.

Để chứng minh điều đó, bạn có thể thử sử dụng biểu tượng (giả) trong serializeBar.cpp (ví dụ: bằng cách gọi hàm giả được thực hiện trong serializeBar.cpp) trước khi gọi bất kỳ chức năng tuần tự hóa nào cho Foo*. Vấn đề sẽ biến mất.

Hy vọng điều đó sẽ hữu ích.

+0

3 năm ... chết tiệt! : D – MOnsDaR

0

Khó có thể nói ... Có nhiều cơ hội cho mọi thứ Đi sai. Tôi khuyên bạn nên tải xuống mã kiểm tra để tăng tuần tự hóa (www.boost.org/doc/libs/1_48_0/libs/serialization/test/). Hãy xem xét các trường hợp thử nghiệm xung quanh Ah, A.cpp và dll_a.cpp (về cơ bản kiểm tra kịch bản của bạn) và cố gắng làm cho nó hoạt động bên ngoài hệ thống kiểm tra tăng cường: sử dụng môi trường xây dựng của bạn, cố gắng sửa đổi các tùy chọn trình biên dịch/liên kết đến phù hợp với các bộ kiểm tra tăng cường cho bộ công cụ của bạn.

Thành thực mà nói, IMHO, tại một số điểm, Boost serialization vượt qua biên giới của những gì là đáng tin cậy có thể với tinh khiết C++ xây dựng mô hình w/o công cụ bên ngoài ...

1

các bộ kiểm tra và demo phân phối với các thư viện serialization chứng minh chính xác cơ sở này. Vì vậy, trước tiên hãy chắc chắn rằng các công trình. Sau đó so sánh ví dụ của bạn với nó.

Robert Ramey

"Thành thực mà nói, IMHO, tại một số điểm, Boost serialization vượt qua biên giới của những gì là đáng tin cậy có thể với tinh khiết C++ xây dựng mô hình w/o công cụ bên ngoài ..."

hmmmmmm - vì vậy nó vượt qua hội đồng quản trị như những gì có thể? Mặc dù vậy, bạn có khá nhiều tinh thần. Nỗ lực lớn đã được chi tiêu để thực hiện mọi thứ được coi là cần thiết cho một gói như vậy để có thể chấp nhận được.

RR

0

Sử dụng BOOST_CLASS_EXPORT đăng ký tất cả các lớp học của bạn mà bạn muốn serialize

Các vấn đề liên quan