Đây là phiên bản được viết lại hoàn toàn của an earlier question; Tôi nghĩ rằng phiên bản đầu tiên bỏ qua các chi tiết quan trọng; cái này cung cấp tất cả ngữ cảnh.Câu đố API C/C++
Tôi có tiêu đề của một số API C++. API tuyên bố một số lớp như sau:
class Foo
{
public:
inline void Bar(void);
/* more inlines */
private:
inline Foo();
/* maybe more inline constructors */
}
I.e. không có thành viên, tất cả các hàm đều là nội dòng và công khai, ngoại trừ các hàm tạo. Các nhà xây dựng là riêng tư, vì vậy, theo như tôi hiểu C++, tôi không thể thực sự gọi chúng. Để tạo các đối tượng này tôi dự định sử dụng auto_ptr
s đối với họ:
class FooAutoPtr : public std::auto_ptr<Foo>
{
public:
inline FooAutoPtr();
/* one for each Foo constructors */
}
API cũng có một bộ thứ hai của các chức năng như thế này:
void Foo_Bar(void *self);
Foo* Foo_Constructor();
Hãy gọi cho họ chức năng cốt lõi, bởi vì đây là những biểu tượng thực sự được xuất từ ứng dụng máy chủ. Không phải các lớp C++.
Chức năng chính có liên kết C (nghĩa là chúng được khai báo là extern "C"
), nhưng chúng được khai báo là lấy và trả về loại C++ (ví dụ: chúng có thể tham chiếu: Foo &foo
). Cuối cùng tiêu đề chứa việc thực hiện các hàm nội tuyến của các lớp C++. Tất cả các chức năng này đều giống nhau: chúng gọi các hàm lõi. Ví dụ, các nhà xây dựng FooAutoPtr
là như thế này:
inline FooAutoPtr::FooAutoPtr()
{
reset(Foo_Constructor());
}
Từ những gì tôi hiểu, mã nhận được một số đối tượng được coi là một con trỏ đến Foo
từ các ứng dụng máy chủ và thay đổi auto_ptr
Gizmo để trỏ đến đối tượng này . Nhưng đối với nhà phát triển, có vẻ như đó là con trỏ thực sự đến Foo
. Và gọi số Foo::Bar()
sẽ diễn ra như sau:
inline Foo::Bar()
{
Foo_Bar(this);
}
Điều này áp dụng cho tất cả các lớp và phương pháp C++. Clever, huh?
Bây giờ, ai đó có thể giải thích điều này có nghĩa là gì? :) Nó không phải là một C++ API thực sự, phải không? Đối với tôi, nó trông giống như một wrapper C++ mỏng trên đầu trang của một API C. Nếu vậy, tôi có thể redeclare các chức năng cốt lõi để mất các bit C++? Tôi hiểu làm thế nào để viết một wrapper C xung quanh C + + (thực sự, tôi đã viết nó), nhưng, nếu có thể, tôi muốn mất wrapper và sử dụng các chức năng trực tiếp. Nhưng làm thế nào để mất các công cụ C++?
Ví dụ, có thể có một chức năng với sự tham khảo:
Bar& Foo_GetBar(void* self, const Baz& baz, int& i);
Ngay bây giờ tôi gọi nó từ C của tôi ++ wrapper như thế này:
typedef struct bar bar_t; /* and others */
/*...*/
bar_t*
foo_get_bar(foo_t* foo, baz_t* baz, int* i)
{
return (bar_t*) &Foo_GetBar(foo, *(Baz*)baz, *i);
}
và nó hoạt động (tôi không có ý tưởng, làm sao). Nhưng tôi thà có nó redeclared như thế này:
/* type? */ Foo_GetBar(foo_t*, /* type? /*, /* type? */);
CẬP NHẬT: Tôi tìm thấy một điều thú vị mà khẳng định Neil's answer. Đó là mã trong Common Lisp sử dụng cùng một API. (Đương nhiên, nó phải sử dụng phần C.) Và, từ những gì tôi có thể (hầu như) đọc trong nguồn, tác giả chỉ đơn giản là sử dụng con trỏ thay cho tham chiếu.Dưới đây là một đoạn trích từ mã chuyển đổi khai báo C++ thành Lisp:
;; use * instead of & - we're not interested in C++ details
line (regex-replace-all "&" line "*")
Vì vậy, đó là nó :) Cảm ơn mọi người!
Wow, một câu hỏi được đặt là _legitimately_ được gắn thẻ cả 'c' và' C++'. Một sự xuất hiện hiếm hoi ... – ildjarn
Nếu các hàm lõi trả về các kiểu C++ (tham chiếu) thì nó _is_ một API C++ sống thực (_not_ a API C), nhưng nó không phải là một đối tượng hướng đối tượng. –
@ SethCarnegie Vì vậy, đó là nó :) Bạn thấy, tiêu đề thậm chí có một bình luận gần các chức năng cốt lõi nói rằng đây là "cho môi trường C-chỉ". Vâng, một bình luận lỗi thời :) –