2009-12-31 6 views
5

Więc jestem architektem aplikacji, która niekoniecznie działa w C++, ale MFC/ATL jest zbyt niechlujny jak na mój gust, więc miałem świetny pomysł na wykonanie całego "myślenia" kodu w natywnym C++ i cały ładny kod UI w języku C#. Problemem jest jednak interoperacyjność między nimi dwoma. Zanim się tym zająłem, zastanawiałem się, czy jest to rozwiązany problem, i jest na to naprawdę dobry sposób. Zauważ, że nie chcę mieszać logiki i wyświetlania w tym samym module, ponieważ powoduje to irytująco wysokie sprzężenie.Native C++ i C# interop

Oto co mam do tej pory:

enter image description here

Więc powiedz mi, można to zrobić lepiej?

+0

Dlaczego musi być C++? – SLaks

+1

Ponieważ istnieje istniejąca podstawa kodu, która udostępnia interfejs API C++ i jest to moja lingua franca. Byłbym zagubiony bez moich wskazówek. –

Odpowiedz

11

Najprostszym sposobem radzenia sobie z tym jest użycie C++/CLI i ujawnienie logiki jako typy .NET.

Bardzo łatwo jest zawinąć natywną klasę C++ w ref class, którą można usunąć bezpośrednio z interfejsu użytkownika C#.

To powiedziawszy - to był mój plan, pierwotnie w moim obecnym projekcie. Myślałem, że potrzebuję kodu natywnego do ciężkiej pracy matematycznej, którą zwykle wykonujemy. Zauważyłem jednak, że łatwiej jest, szybciej i ładniej przenieść większość logiki bezpośrednio do C# (oddzielonej od kodu UI, ale wciąż w zespole C#), zamiast próbować implementować ją w C++.

Moje doświadczenie jest takie, że prędkość nie była problemem - niebezpieczny kod C# prawie zawsze był tak szybki lub szybszy od porównywalnego C++ po dostrojeniu i łatwiej jest profilować i dostroić kod C#.

+0

Czy kod opakowania umieszczony w Proxy.dll jest w zasadzie tą samą strategią? Czy mogę uznać to za "dobrze dla mnie wyglądające"? –

+0

Jeśli chodzi o część interfejsu .NET/C++, tak, wygląda dobrze. Zrobiłem to samo z istniejącą bazą kodu w C++, gdzie chciałem zrobić GUI w C#. – AaronLS

+0

Ja też przepisałem kod C na C# i byłem bardzo zadowolony z wydajności, którą widziałem. Musiałaby to być bardzo intensywna procesorowa aplikacja, aby tego nie zauważać. –

1

Możesz mieć dobry powód, aby Twój rdzeń był biblioteką DLL. Ale nie jest to konieczne. Odniosłem sukces z aplikacją w języku C++, tworzy ona domenę aplikacji i ładuje do niej zestaw, a następnie tworzy instancję obiektu w domenie aplikacji i wywołuje go, przekazując mu interfejs do aplikacji. Jest to w zasadzie to, co robi C-runtime, kiedy i tak robisz niezarządzaną aplikację.

Interfejs, który kod C++ udostępnia do kodu C# jest zdefiniowany w C#. Myślę, że jest to łatwiejsze niż definiowanie intefaces w czystej COM. C# interop zapewnia większą kontrolę nad ładowaniem niż w C++.

  • utworzyć plik app_interface.cs który definiuje interfejs
  • kompilacji app_interface.cs do biblioteki dll, nie dbamy o dll. potrzebujemy biblioteki typów.
  • w C++ kod #import <app_interface.tlb> raw_interfaces_only ten włącza TypeLib w C++ .h plik z definicjami interfejsów: app_interface.tlh
  • zaimplementować interfejsy

Można posypać swoje app_interface.cs z atrybutami, które kontrolują rozrządowych tak jak ten

[ComVisible(true)] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
[Guid("ffffffff-ffff-ffff-ffff-ffffffffffff")] // guid changed from what I really use 
public interface IMyHostApplication 
{ 
    ... 

    void AddErrorDetails (
     [MarshalAs(UnmanagedType.Error)] uint hr, 
     [MarshalAs(UnmanagedType.LPWStr)] string szErrDetails); 

    ... 
} 
+0

Chciałbym oddzielić kod C++ od kodu C# tak bardzo, jak to możliwe, zachowując powierzchnię do minimum. Ponadto nie chcę myśleć o zarządzanym kodzie, podczas gdy robię natywny. –

+0

Głównym punktem jest to, że rozpoczynając od zera łatwiej jest zdefiniować inteface między dwiema częściami w C# od samego początku. #import gwarantuje, że to, co zobaczą w C++ i C# jako definicja interfejsu, pochodzi z pojedynczego pliku. –

+0

Bez względu na to, jak to robisz, zdecydowanie powinieneś spróbować zminimalizować powierzchnię interfejsu między C++ i C# –