2013-04-23 7 views
6

Moje poprzednie pytanie nie powiodło się ("C# biblioteka AnyCPU korzystająca z API C x86/x64 - struktury, połączenia i wywołania zwrotne") Napiszę bardziej zwięzły i abstrakcyjny.Wyrównanie struktury C++ x86/x64 + .NET AnyPCU Wykorzystanie biblioteki C++ (wywołania/wywołania zwrotne)

obrazka:

Firma, gdzie pracuję posiada oprogramowanie do być przeniesione na 64 bit. Oprogramowanie składa się z biblioteki BASE (C++ z C API) i dwóch wrapperów nad API C: otoki C++ i otoki .NET.

Biblioteka C++ BASE & C++ WRAPPER powinien mieć konfiguracje kompilacji x86/x64. .NET WRAPPER powinien mieć tylko konfigurację kompilacji AnyCPU.

Wybór odpowiedniej biblioteki z .NET WRAPPER został pomyślnie zakończony (obie biblioteki C++ BASE (x86/x64) są ładowane w dwóch osobnych przestrzeniach nazw iw zależności od wielkości IntPtr w prawym rogu wywoływane są odpowiednie funkcje; niekoniecznie wymaga obecności obu bibliotek, ale tylko tej, która ma być używana).

problem:

Wszystkie struktury w bibliotece zasad są dostosowane 4 bajtów:

#pragma pack(push,4) 

W celu uzyskania kodu podczas kompilacji żadne ostrzeżenia w 64-bitowym, muszę dodaną selektywną dopasowanie (C++, C++ PODSTAWA & pracy WRAPPER jak charms)

#ifdef WIN64 
#pragma pack(push,8) 
#else 
#pragma pack(push,4) 
#endif 

problemem jest związane ze strukturami .NET:

[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)] 
    internal struct DBConnectionSettings{...} 

Ta struktura nie może mieć selektywnego pakowania, ponieważ AnyCPU jest jedyną pożądaną konfiguracją WRAPPER.

To jest bardzo trudne (wiele i dużo błędów w wyniku działania), aby utworzyć oddzielne struktury wyrównane na 8 bajtów w innej przestrzeni nazw .NET ... To może być jednak jedyne rozwiązanie, które możemy znaleźć w pełni działające.

Powrót do wyrównania 4-bajtowego dla problemów x86 i x64 DUŻO ostrzeżeń jako 100% struktur jest wrażliwych na pakowanie, szczególnie dla operatorów jednoargumentowych (problemy pojawiają się tylko w konfiguracji rozwiązania x64 z wyrównaniem na 4 bajtach). Wiele awarii, struktury nie mogą być wyrównane, chyba że dodamy fałszywe elementy. Powinienem wspomnieć, że struktura jest pogrupowana na podstawie znaczenia lub powiązana z systemem licencji/docelowego systemu operacyjnego (ifdefs). Dodanie członów wyściółki (dummy) do wszystkich możliwości wymagałoby miesięcy.

Wyrównanie wszystkiego na 8 bajtów nie jest rozwiązaniem, ponieważ nie dostaniemy awarii ponownie na miejsce - tylko dla x86, x64 działa dobrze - wyrównanie struktury wymaga ponownie manekina (wypełnienia) i grupowania w oparciu o rozmiar.

zawarcia (pytania):

1) Czy jest to możliwe dla kodu C++ uzyskania wyrównania 4 dla obu konfiguracjach x86 i x64 rozwiązanie? Jak to osiągnąć?

2) Jaka jest najlepsza alternatywa dla wyrównania x86 i x64? Rozmiar wskaźnika zdecydowanie powinien rządzić wyrównaniem (moim zdaniem). Staramy się mieć oprogramowanie FAST, niekoniecznie wydajne pod względem pamięci (do tej pory odciski palców pamięci wynoszą od 15 do 2 GB w systemach x86).

3) Jakie potrzeby mają specjalną konstrukcje nośne wskaźników funkcji mają w odniesieniu do współdziałanie między .NET i C?

4) sugerowanych alternatywa jest wysoko cenione.

Szukaliśmy więcej niż jeden miesiąc w tym Internecie (ten na naszej planecie), ale nigdzie nie dotarliśmy. Niektórzy architekci twierdzą, że używają selektywnego pakowania (4/8), podczas gdy niektórzy twierdzą, że oprogramowanie nie jest proste i powinno być refaktoryzowane. To nie moja decyzja co robić, ale mogę wnosić pomysły z dobrymi argumentami. Oprogramowanie zostało uruchomione pod koniec 2000 roku, kiedy STL był błędny, więc BASE ma swoje własne kontenery zoptymalizowane dla Boga-wie-co. Nie powinienem tutaj wyrażać mojej opinii, ponieważ nie jest ona chrześcijańska.

Odpowiedz

1

Po prostu napraw problem wyrównania po stronie C++. Nie powinno być żadnego powodu, aby kod x86 powodował awarię w 8-bitowym wyrównaniu, ani x64, aby zawiesić się na 4-bajtowym wyrównaniu. #pragma pack(push,4) byłby odpowiednią metodą. Możesz potrzebować kolejnego #pragma pack dla wewnętrznego kodu SSE, ale ten kod nie powinien być narażony na kod AnyCN .Net.

Jeśli masz setki ostrzeżeń (pomijając perf. Ostrzeżenia oczywiście), następnie kompilator zgadza się z moją oceną, że kod jest podejrzany.

+0

Witryna MSalters, Bez żadnych danych zdecydowano, że ponowne wyrównanie zostanie wykonane, niezależnie od struktury zależnej od systemu i systemu. Nadal pozostawiam ten temat otwarty dla wszelkich innych rozwiązań, które mogą być publikowane. Po prostu ciekawi mnie, co można zrobić z takim kodem ..... PS: to nie mój kod;) – ro0ter