2011-11-11 33 views
5

Tôi thực sự cần sự hiểu biết sâu hơn về cách thiết lập mọi thứ để có được sự tương tác thanh lịch giữa các cơ sở mã C + + và C# của tôi. Điều tôi muốn đạt được là một trình soạn thảo trong trò chơi được viết bằng C# cho công cụ trò chơi của tôi (C++/DX). Để làm như vậy, tôi cho VS xây dựng engine của tôi như một dll C++ với một số chức năng bổ sung (mã không được quản lý) để truy cập chức năng cần thiết của động cơ của tôi từ cơ sở mã trình soạn thảo C#. Càng xa càng tốt.Làm thế nào để xử lý tương tác dự án C# - C++ đúng cách?

Điều đầu tiên làm tôi lo ngại là tôi sẽ xây dựng dll với hỗ trợ CLR. Nếu không, C# không chấp nhận dll vì lý do nào đó. Nó thậm chí không cho phép tôi thêm nó vào tài nguyên ("Tham chiếu đến 'C: \ Users ... \ frame_work \ Test \ frame_workd.dll' không thể được thêm vào. Vui lòng đảm bảo rằng tệp có thể truy cập và rằng nó là một thành phần hợp lệ hoặc COM. ").

Và khi tôi xây dựng dll với hỗ trợ CLR và thêm nó vào các tham chiếu trong C#, xây dựng lại mà không cần hỗ trợ CLR, khởi động trình soạn thảo của tôi và thực hiện cuộc gọi hàm từ dll thì tôi nhận được một ngoại lệ HRESULT: 0x8007007E. Tôi đã tìm kiếm nó nhưng điều duy nhất tôi tìm thấy phải làm với các phụ thuộc nhưng điều đó không phù hợp với cảnh báo tôi nhận được khi thêm dll vào tài nguyên.

Điểm khác là tôi luôn phải chuyển đổi loại cấu hình giữa ứng dụng (.exe) và dll. trong VS C++ tùy thuộc vào việc tôi muốn chạy động cơ của tôi trực tiếp hoặc từ trình soạn thảo và mỗi khi dự án hoàn thành được xây dựng hoàn toàn mới.

Vì vậy, ai đó có thể giải thích cho tôi cách tổ chức đúng cách này? Và những gì có thể là một lý do có thể tại sao C# muốn dll được biên dịch với sự hỗ trợ CLR?

Cảm ơn các bạn/cô gái.

Trả lời

1

Có hai cách để giải quyết vấn đề này.

Hoặc bạn tạo mã C++ cung cấp API có đối tượng COM hoàn toàn tuân thủ. Nếu đối tượng là COM thì C# có thể trực tiếp tương tác với nó. (Đây là lý do tại sao bạn không thể thêm nó làm tài liệu tham khảo trực tiếp)

Tuy nhiên tôi nghĩ những gì bạn thực sự muốn làm sẽ liên quan đến P/Invoke (gọi mã gốc C/C++ từ C#). Điều này hoàn toàn có thể nhưng không phải lúc nào cũng dễ dàng. Bạn cần phải đối phó với các chuyển đổi giữa C++ API của bạn và C#, con trỏ của bạn và bạn cần phải rất cẩn thận để ghim bất kỳ tài liệu tham khảo mà mã C + + của bạn viết vào trong ứng dụng C#.

1

Mã C# là mã được quản lý (chạy trong CLR) và chỉ có thể trực tiếp * cụm được quản lý tham chiếu. Vì vậy, khóa học bạn đang gặp lỗi khi bạn xây dựng dựa trên một hội đồng được quản lý và sau đó lẻn vào và thay thế DLL được quản lý đó bằng một DLL không được quản lý (không tương thích). Về cơ bản bạn đang cố gắng nói dối với trình biên dịch, và nói chung không kết thúc tốt.

Nếu bạn muốn tệp C++ DLL của bạn có thể truy cập được từ C#, cách đơn giản nhất để thực hiện nó là xây dựng nó như một assembly được quản lý (ví dụ, hỗ trợ CLR). Mà bạn đang thực hiện . Chỉ cần đưa ra các bước bổ sung, nơi bạn thay thế DLL được quản lý làm việc với một không làm việc không quản lý một.

Ngoài ra:

C++ dll với một số chức năng bổ sung (unmanaged code) để truy cập các chức năng cần thiết của động cơ của tôi từ C# biên tập

Điều đó sẽ không giúp bạn, bởi vì C# có thể 't trực tiếp * gọi mã không được quản lý. Cách đơn giản nhất để thực hiện công việc này là tạo thêm các lớp và phương thức quản lý trong C++ DLL của bạn. Sau đó, hội đồng C# của bạn sẽ có thể trực tiếp sử dụng các lớp được quản lý đó.

* Như Spence noted, bạn có thể sử dụng phương tiện -indirect- (P/Invoke và COM) để truy cập unmanaged code từ C#. Nhưng điều đó sẽ làm cho cuộc sống của bạn phức tạp hơn nhiều so với hiện tại, chưa kể làm thế nào nó sẽ làm phức tạp việc xây dựng và triển khai của bạn. Bạn đã thực sự gần với một cái gì đó sẽ làm việc - không thêm tất cả những phức tạp thêm.

+0

Mọi thứ hoạt động tốt ngay bây giờ. Sai lầm duy nhất là một thực tế là tôi đã thêm dll vào tài liệu tham khảo, nghĩa là địa điểm sai. Nó bây giờ làm việc mà không có sự hỗ trợ CLR. Cảm ơn bạn đã trả lời của bạn. @Spence – user1042568

+0

Có khả năng buộc api của bạn được quản lý không phải lúc nào cũng là một lựa chọn. – Spence

1

Khi gọi các hàm bằng P/Invoke, bạn không thêm DLL vào tài nguyên dự án C# (hoặc ý bạn có thể là gì, tham chiếu).

Bạn sẽ thêm nó vào danh sách tệp trong dự án MSI của bạn, tất nhiên.

+0

Bạn đang đúng những gì tôi có nghĩa là 'tài liệu tham khảo'. Tôi nghĩ rằng đây là nơi thích hợp để đặt nó vì tôi luôn luôn có một bản sao cập nhật của dll của tôi được đặt trong thư mục ứng dụng của trình soạn thảo của tôi. Tuy nhiên, cảm ơn. – user1042568

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