2010-07-13 21 views
22

Tôi có một thư viện bao gồm ba phần. Đầu tiên là C++ bản địa, cung cấp chức năng thực tế. Thứ hai là trình bao bọc/bộ chuyển đổi C++/CLI cho thư viện C++, để đơn giản hóa quá trình chuyển đổi C# thành C++. Cuối cùng tôi có một thư viện C#, nó gọi thư viện C++ thông qua bộ chuyển đổi C++/CLI.Chia sẻ enum từ C#, C++/CLI và C++

Ngay bây giờ ở đó, tôi có hai bộ định nghĩa enum song song, một tệp được lưu trữ trong tệp .cs và tệp còn lại trong tệp .h. Điều này đặt ra một vấn đề đôi:

  1. Tôi có bảo trì kép. Tôi phải luôn luôn đồng bộ hóa các thay đổi của một enum ở cả hai vị trí tập tin.
  2. Không gian tên được sử dụng bởi cả hai enums phải giống hệt nhau nhưng trình bao bọc C++/CLI, xem cả hai tập hợp các enums và dịch giữa chúng, phát sinh một va chạm đặt tên.

Ngay bây giờ tôi không chắc chắn một giải pháp như this hoặc that sẽ giải quyết cả vấn đề. Suy nghĩ?

+1

không trùng lặp nhưng thấy câu hỏi tương tự: http: // stackoverflow.com/questions/954321/is-it-possible-to-share-an-enum-khai báo-giữa-c-và-không được quản lý-c –

+0

có thể trùng lặp của [Làm cách nào để chia sẻ một hằng số giữa mã C# và C++?] (http://stackoverflow.com/questions/3146017/how-do-i-share-a-constant-between-c-and-c-code) –

+0

@Billy: nó không phải là một bản sao, vì lớp C++/CLI ở đây cung cấp một số tùy chọn bổ sung. Tuy nhiên, câu trả lời ở bài đăng bạn đưa ra cũng có thể hữu ích, ở đây. –

Trả lời

2

Chỉ cần đặt chỉ thị #include "Enum.cs" của bạn bên trong một không gian tên bên ngoài để giải quyết xung đột tên.

EDIT: Một biến thể được đề xuất bởi Brent là sử dụng #define để thay thế một trong các không gian tên (hoặc thậm chí cả tên enum) được khai báo trong tệp .cs. Điều này cũng tránh được sự va chạm đặt tên, mà không làm cho hệ thống phân cấp không gian tên sâu hơn.

+0

Bạn có đọc nhận xét của tôi về Mystagogue trong bài đăng đầu tiên của tôi không? –

+0

Phương pháp của bạn không cho phép sử dụng cùng một tệp nguồn trực tiếp trong C# và các dự án C++ gốc. Mỏ không yêu cầu macro. –

+0

Phương pháp của bạn không cho phép truy cập vào enum được quản lý từ dự án C++/CLI, chỉ với enum không được quản lý. Vì vậy, nó không phù hợp với yêu cầu của OP. –

9

Thậm chí nếu bạn bao gồm C# enum trong C++ gốc của bạn (như được đề xuất trong first link), cả hai enums không phải là "giống nhau", C++ enum là gì, nhưng danh sách các số nguyên được đặt tên, trong khi C# enum có nguồn gốc từ Enum. Kết quả là, bạn nhận được một va chạm trong C++/CLI khi cố gắng sử dụng chúng cả hai.

Một giải pháp khả thi là sử dụng tiền xử lý để C++/CLI lắp ráp của bạn thấy cả hai enums trong không gian tên khác nhau:

// shared_enum.h 

#undef ENUMKEYWORD 
#undef ENUMNAMESPACE 

#ifdef MANAGED 
#define ENUMKEYWORD public enum class 
#define ENUMNAMESPACE EnumShareManaged 
#else 
#define ENUMKEYWORD enum 
#define ENUMNAMESPACE EnumShare 
#endif 

namespace ENUMNAMESPACE 
{ 
    ENUMKEYWORD MyEnum 
    { 
     a = 1, 
     b = 2, 
     c = 3, 
    }; 
} 

Trong mã C++/CLI của bạn, làm cho một bao gồm như thế:

#undef MANAGED 
#include "shared_enum.h" 
#define MANAGED 
#include "shared_enum.h" 

Tính năng này cung cấp cho bạn tính khả dụng để phân biệt giữa hai loại nội dung đó EnumShare::MyEnum hoặc EnumShareManaged::MyEnum trong mã C++/CLI của bạn.

CHỈNH SỬA: chỉ tìm thấy this SO post hiển thị đúng cách để truyền giữa các thư mục không được quản lý và được quản lý, điều này chắc chắn cũng sẽ hoạt động ở đây. Ví dụ, trong C++/CLI, sự chuyển đổi từ quản lý để enum không được quản lý có thể được thực hiện như thế này:

void MyWrapperClass::MyWrapperFunction(EnumShareManaged::MyEnum mx) 
{ 
    EnumShare::MyEnum nx = static_cast<EnumShare::MyEnum>(mx); 
    // call a native function "func" 
    func(nx); 
} 
+0

Cách tổ hợp C# xem tập tin "shared_enum.h"? Tôi đoán nó là dễ dàng hơn để có C++ #include một "shared_enum.cs" hơn là có C# bằng cách nào đó hấp thụ một "shared_enum.h". Vâng? –

+1

@Mystagogue: nếu bạn bao gồm shared_enum.h trong một trong các tệp CPP của bạn (của dự án C++/CLI), enum được quản lý trở thành một phần của assembly, và nếu bạn tham khảo assembly này từ C#, nó có thể nhìn thấy ở đó vì nó được tuyên bố là 'công khai'. Mặt khác, nếu bạn khai báo enum được quản lý trong một "shared_enum.cs", nó sẽ không được hiển thị trong dự án C++/CLI của bạn, vì C++/CLI không tham chiếu đến dự án C# của bạn, chỉ ngược lại. –

+0

Ah! Vâng, nhưng darn! Yêu cầu bổ sung: Tôi cần hỗ trợ cả triển khai x86 và x64. Mã Client C# "AnyCPU" của tôi hiện đang tham chiếu đến một assembly C# chứa các giao diện và các định nghĩa enum. C++/CLI x86/x64, cũng tham chiếu đến người trung gian, được nạp một cách rõ ràng vào thời gian chạy bởi máy khách C#, dựa trên kiến ​​trúc. Tóm lại, tôi không thể sử dụng một kỹ thuật phụ thuộc vào tham chiếu C# "build-time" vào trong C++/CLI assembly. –

3

Xem xét văn bản chương trình tạo mã, mà đọc tập tin bản địa h-file với kiểu liệt kê và tạo ra một h-file , chuyển đổi enum thành lớp C++/CLI enum. Bộ tạo mã như vậy có thể được sử dụng trong dự án C++/CLI trên Custom Build Step, tạo ra các liệt kê CLI yêu cầu.

Tôi sử dụng phương pháp này để tạo các lớp trình bao bọc gốc để có được các hàm Enum :: GetNames và Enum :: GetName trong C++ không được quản lý.

+0

Cũng sử dụng phương pháp này khi giao dịch với khoảng 50 enums trong một dự án lớn. Phần quan trọng nhất là thiết lập các điều tra viên enum được quản lý thành các giá trị điều tra chưa được kiểm tra. –

+0

Ngay cả với trình tạo mã (có thể hữu ích nếu bạn có nhiều enums), bạn phải giải quyết bằng cách nào đó với vấn đề đặt tên va chạm. Đề xuất của tôi là "sống với các không gian tên khác nhau và xử lý chúng một cách chính xác". Có ý tưởng nào tốt hơn không? –

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