2012-05-14 23 views
5

của thư viện C++ của tôi Tôi đang phát triển thư viện C++, nơi người dùng sẽ cung cấp các đầu vào phức tạp, chẳng hạn như ma trận và quaternions . Tôi không muốn phải triển khai lại các loại này, vì vậy, nội bộ, tôi sẽ sử dụng thư viện Eigen.Các loại bên thứ ba sẽ được hiển thị trong API

Tôi đang cố gắng quyết định cách tốt nhất để hiển thị các loại này cho các khách hàng của thư viện của tôi và đã đưa ra một vài tùy chọn cho API của tôi. Tôi sử dụng một loại quaternion làm ví dụ, nhưng điều này có thể áp dụng như nhau đối với ma trận và như vậy. Ngoài ra, mặc dù tôi đang nói cụ thể về việc phơi bày các loại của Eigen, tôi đoán câu hỏi này có thể áp dụng tốt cho các thư viện bên ngoài khác đang được sử dụng.

1) Sử dụng C++ loại chỉ cơ bản

Tùy chọn này sẽ yêu cầu khách hàng để truyền dữ liệu trong thông qua loại hình cơ bản. Đối với Ví dụ, để thông qua trong một quaternion (4 yếu tố), người ta có thể làm:

void my_func(double my_quat[4]) 

2) Đưa ra các loại Eigen của

Eigen cung cấp một số loại templated cho mảng và quaternions. Đối với Ví dụ, nếu một chức năng đòi hỏi một quaternion, tôi có thể sử dụng Eigen của Quaterniond loại (mà thực sự là một typedef cho Quaternion<double>):

void my_func(const Eigen::Quaterniond& my_quat) 

3) Tạo một wrapper đơn giản cho các loại khác nhau cho khách hàng

tôi có thể tạo ra một loại rất đơn giản quaternion (nói, một số loại cấu trúc đơn giản) mà khách hàng sẽ phải tạo (có lẽ qua một số loại chức năng nhà máy) để chuyền qua API của tôi:

void my_func(const quaternion_t& my_quat) 

Thư viện của tôi sẽ chuyển đổi loại quaternion_t thành biểu diễn Eigen nội bộ của tôi.

Tôi không thích tùy chọn 1 quá nhiều vì tôi muốn có ý nghĩa mạnh mẽ hơn về việc nhập vào API của tôi. Tùy chọn 2 cũng sẽ yêu cầu khách hàng của tôi sử dụng Eigen, chứ không phải để đề cập đến các vấn đề tiềm năng với khả năng tương thích nếu họ sử dụng phiên bản khác nhau của Eigen (Eally là thư viện chỉ tiêu đề nếu số vấn đề). Tùy chọn rời khỏi tùy chọn 3.

Mọi người nghĩ sao? Tôi đã trả lời câu hỏi của riêng mình chưa? Có ví dụ nào không?

Câu hỏi liên quan

Một câu hỏi liên quan được hỏi here nhưng không thực sự đi sâu vào chi tiết về việc liệu một nên lộ loại bên ngoài.

+0

Còn tùy chọn 3, với các nhà thầu chọn cả hai lựa chọn 1 và 2 thì sao? Ngữ nghĩa C++ cho phép bạn chuyển tiếp các kiểu khai báo đủ tốt để làm việc này (các máy khách không có Eigen vẫn có thể bao gồm tiêu đề và không thất bại trong thời gian biên dịch). – Lalaland

+0

Tôi đã suy nghĩ về một cái gì đó như thế, nhưng tôi đoán tôi là một chút mờ về làm thế nào để chuyển tiếp khai báo kiểu typedef'd mẫu, mặc dù tôi đoán trong trường hợp của tôi, tôi có lẽ sẽ giới hạn khách hàng để đi qua một instantiation cụ thể của các loại (như 'Quaternion ' trái với 'Quaternion '). – plasma

+0

Tôi cũng hơi mờ về những gì sẽ xảy ra nếu một khách hàng sử dụng hàm tạo để tạo kiểu thư viện của tôi từ kiểu Eigen của họ, nhưng họ đang sử dụng một phiên bản khác của Eigen có thể có một thay đổi nhỏ. – plasma

Trả lời

2

Gói/đóng gói. Giả sử bạn muốn thêm một số tính năng bổ sung, chẳng hạn như lưu vào bộ nhớ cache kết quả của phép tính, như chỉ tiêu của quaternion, như là một thay đổi thực hiện.Bạn không thể làm điều đó (dễ dàng) nếu bạn phơi bày các loại của bên thứ ba mà không buộc mã máy khách thay đổi cuộc gọi của mình.

+0

Tôi đồng ý. Tuy nhiên, tôi không nhất thiết muốn phơi bày toàn bộ ma trận/quaternion/etc. thư viện của riêng tôi, vì chức năng của thư viện của tôi sẽ ở mức cao hơn. Nó có ý nghĩa đối với các lớp trình bao bọc của tôi để cung cấp một số lượng tối thiểu chức năng để giao tiếp với API của tôi và cho phép khách hàng sử dụng bất kỳ thứ gì họ muốn để thực sự thao tác dữ liệu được liên kết với các loại đó không? – plasma

+0

Trình bao bọc mỏng là OK. my_quaternion :: foo() {return their_quaternion.foo(); } là tốt cho các chức năng bạn muốn phơi bày. Như @Attila chỉ ra ở trên trường hợp ấn tượng nhất là một trong đó bạn muốn chuyển đổi thư viện, một rắc rối khách hàng của bạn không cần phải giải quyết. Nếu bạn cảm thấy khách hàng sẽ cần quyền truy cập hạng nặng vào các đối tượng toán học chính thức từ eigen: Cũng cung cấp hàm getEigen() và một ctor lấy eigen làm đầu vào để đến và fro mà bạn sẽ đảm bảo sẽ luôn hoạt động ngay cả khi bạn thực hiện lại trong thư viện khác. – djechlin

+0

Điều gì sẽ xảy ra nếu khách hàng sử dụng hàm ctor hoặc getEigen() và thư viện của tôi được biên dịch với các phiên bản khác nhau của Eigen? Tôi giả định rằng nếu cả hai phiên bản đều tương thích với ABI, thì chúng tôi rất tốt. Nhưng nếu một cái gì đó nên thay đổi, điều này sẽ không hoạt động nữa? Đặc biệt, tôi đang nghĩ về trường hợp tôi cung cấp thư viện của mình như một DSO, nhưng tôi đoán tôi không biết điều gì sẽ xảy ra nếu tôi đưa cho khách hàng một thư viện tĩnh. – plasma

2

Việc trưng ra thư viện của bên thứ ba là dễ dàng nhất trong ngắn hạn, nhưng rất có thể sẽ khiến bạn khó chịu về lâu dài. Dễ nhất, bởi vì các loại có độ đồng đều ở đó, bạn không cần phải tự mình làm ra. Sẽ cắn bạn nếu bạn muốn sử dụng thư viện triển khai khác trong tương lai hoặc muốn cho phép mở rộng dữ liệu mà khách hàng chuyển cho bạn.

Chỉ sử dụng các loại cơ bản gần giống như sắp xếp theo cách của riêng bạn, nhưng ở cấp độ thấp hơn nhiều, không có lý do chính đáng. Người dùng của bạn sẽ gặp khó khăn khi sử dụng thư viện của bạn mà không liên tục tham khảo tài liệu về những gì.

Sử dụng các loại của riêng bạn là tùy chọn tốt nhất nếu bạn muốn linh hoạt xuống dòng. Nó có vẻ như rất nhiều công việc ở phía trước vì bạn cần phải tạo lại tất cả các kiểu đã tồn tại, nhưng nếu bạn cho nó một chút, bạn có thể thấy rằng nếu bạn sử dụng các kiểu hơi khác nhau trong giao diện của thư viện, nó sẽ tạo điều kiện cho việc thực hiện thay đổi tốt hơn sau này. Vì vậy, câu trả lời thực sự phụ thuộc vào mục tiêu và kế hoạch/dự đoán dài hạn của bạn: nếu bạn không thấy mình thay đổi từ việc triển khai hiện tại, bạn có thể sử dụng lại các kiểu hiện có, nhưng nếu bạn thấy trước/thay đổi kế hoạch trong tương lai, bạn nên tạo giao diện độc lập của riêng mình.

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