Pole w strukturze niewidoczne w dll

0

Cześć, pewnie kombinuję, ale czy da się zrobić coś takiego, że...

Mam sobie strukturę w C++:

struct MyStruct
{
  __int32 iValue;
  bool bValue;
}

I teraz pobieram sobie tą strukturę w C# za pomocą API. Struktura w C# wygląda tak:

[StructLayout(LayoutKind.Explicit)]
public struct MyStruct
{
  [FieldOffset(0)]
  public Int32 iValue;

  [FieldOffset(4)]
  public bool bValue;
}

Czy jest możliwe, żebym dodał do struktury w C# pole typu string, które nie byłoby brane pod uwagę w API? Za pomocą jakiegoś atrybutu lub szarpowej sztuczki.

Do głowy przychodzi mi jeszcze (C#) nowa struktura, dziedzicząca po MyStruct i mająca to dodatkowe pole.

1

Przede wszystkim nie dodaje się pól typu string do struktur.

0

Czemu nie?

4

bo struktura zawsze bedzie kopiowana wraz ze wszystkimi polami.
string w C# jest immutable. Zastanow sie teraz co sie stanie gdy bedziesz przekazywac do funkcji ta strukture

1

Do głowy przychodzi mi jeszcze (C#) nowa struktura, dziedzicząca po MyStruct i mająca to dodatkowe pole.

Struktury w C# nie mają dziedziczenia.

Raczej opakuj to w klasę i dodaj stringa jako pole.
Albo stwórz słownik Dictionary<MyStruct, string>.

0
fasadin napisał(a):

bo struktura zawsze bedzie kopiowana wraz ze wszystkimi polami.
string w C# jest immutable. Zastanow sie teraz co sie stanie gdy bedziesz przekazywac do funkcji ta strukture

Kopia struktury będzie trzymała referencję do oryginalnego stringa.

A mi nie chodzi o to, żeby to przekazywać do funkcji API. Bynajmniej.

Pokażę przykład, co bym chciał osiągnąć:

public struct MyStruct
{
  public Int32 iValue; //"przejdź" przez API
  public bool bValue; //"przejdź" przez API
  public string name; //nie przechodź przez API, API Cię nie widzi, pole tylko do użytku po stronie C#
}

void Foo()
{
  MyStruct s;  
  callApiFunc(ref s);

  s.name = callAnotherApiFunc(s.iValue);
}
2
Juhas napisał(a):

Kopia struktury będzie trzymała referencję do oryginalnego stringa.

specjalnie mowilem Ci zebys sie zastanowil (wiec takze sprawdzil)

http://stackoverflow.com/questions/9203516/struct-containing-reference-types

Nie bedzie trzymal referencji do oryginalnego obiektu stringa

0

Struktury służą do trzymania grupy prostych wartości stanowiących jakąś sensowną całość, która mieści się w 16 bajtach.
Dlaczego w ogóle chcesz użyć struktury, a nie klasy?

3

Czyli, że co. Skopiuje sobie oryginalnego stringa w nowe miejsce? Bo już nie ogarniam.

Wyobraź sobie strukturę:

struct MyStruct
{
  public string s;
}

I teraz masz:

MyStruct m1;
m1.s = "Ala ma kota";
MyStruct m2 = m1;

Póki co w obu obiektach jest referencja do tego samego stringa. Teraz jeśli przypiszesz do pola jedego obiektu nowy tekst:

m2.s = "Ala jest w ciąży";

Od tego momentu oba obiekty zawierają inny string. A to dlatego, że przypisanie do m2.s nie zmienia stringa pod referencją, tylko tworzy nowego stringa i do m2.s wpisuje referencję na nowego stringa, nie ruszając w ogóle m1.s.

0
somekind napisał(a):

Struktury służą do trzymania grupy prostych wartości stanowiących jakąś sensowną całość, która mieści się w 16 bajtach.
Dlaczego w ogóle chcesz użyć struktury, a nie klasy?

Hmm, myślałem, że jeśli po stronie C++ jest struktura, to po stronie C# też musi być. Poza tym nie wiem, jak tutaj wygląda sprawa z Interop.

0
Juhas napisał(a):

Hmm, myślałem, że jeśli po stronie C++ jest struktura, to po stronie C# też musi być. Poza tym nie wiem, jak tutaj wygląda sprawa z Interop.

Różnica między klasa a strukturą w C# jest znacznie większa niż w C++. Struktury w C# mają zupełnie inny model przekazywania (przez wartość, a nie referencję), więc ich nieopatrzne użycie może zabić wydajnościowo aplikację, oraz doprowadzić do niezrozumiałego działania aplikacji (czemu ta wartość się nie zmienia, skoro ją zmieniam!).
Typowy developer C# ma potrzebę użycia struktury raz na 40 lat.

1 użytkowników online, w tym zalogowanych: 0, gości: 1