DLL w C++, użycie w C# (Windows Form App)

0

Witam, chciałbym zadać kilka pytań dotyczących platformy .NET, a w szczególności połączeniu kodu C++ i C# w jeden projekt.

Otóż pracuje nad pewnym (większym niż zazwyczaj) projektem w C++ (coś w rodzaju kalkulatora), w którym zamierzam użyć okien (Windows Form), ale problem jest taki że Visual Studio 2013 nie wspiera okienek dla C++ (C++/CLI). Moim alternatywnym rozwiązaniem jest utworzenie biblioteki DLL napisanej w C++ do obsługi obliczeń, a do okienek użyć C# (chociaż nie do końca, patrz niżej). I tu pojawia się kilka pytań, a mianowicie:
Czy kod DLL, musi być napisany w C++\CLI, czy może być w natywnym C++?
Druga sprawa to czy jeśli wybiorę C++\CLI to czy mogę w jakikolwiek sposób wpływać z kodu napisanego w DLL, na wygląd okienka napisanego w C#, jeśli tak to jak to zrobić?
Czy w C++\CLI jest dostępna przestrzeń nazw System::Forms, w pliku DLL tak jak to było w Visual Studio 2010?
Ogólnie zmierzam do tego żeby za pomocą jednej klasy w C++ w DLL zarządzać całą aplikacją, czyli jeśli załóżmy mam obiekt o nazwie suma, to jego obiektami są oczywiście dwie liczby, oraz dwa TextBoxy, których mogę, nie mogę? użyć w DLL.

Jak widać temat ociera się o koncepcję programowania obiektowego wobec aplikacji graficznych, chętnie wysłucham wszelkich rad jak najlepiej "reprezentować rzeczywistość" w tego typu aplikacjach.

Będę bardzo wdzięczny za wszelkie odpowiedzi i z góry przepraszam za dość chaotyczne przedstawienie problemu.
Pozdrawiam Izi!

3

ale problem jest taki że Visual Studio 2013 nie wspiera okienek dla C++ (C++/CLI).

Wspiera. Brakuje tylko kreatora nowego projektu. Ale można go zrobić ręcznie:
Utwórz projekt CLR Console, dodaj do projektu formę (Ctrl+Shift+A, UI, Windows Form).

W opcjach linkera w zakładce System ustaw subsystem na Windows, a w zakładce Advanced ustaw entry point na main.
Plik z funkcją main() powinien wyglądać tak (zmień tylko nazwy projektu i formy):

// cppwinforms.cpp : main project file.

#include "stdafx.h"
#include "Form1.h"

using namespace cppwinforms;

[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
	// Enabling Windows XP visual effects before any controls are created
	Application::EnableVisualStyles();
	Application::SetCompatibleTextRenderingDefault(false); 

	// Create the main window and run it
	Application::Run(gcnew Form1());
	return 0;
}

W ten sposób otrzymujesz projekt Windows Forms identyczny z tym generowanym przez VS 2010 i starsze.
I podpowiadanie składni nawet działa, czego nie miałeś w 2010.

A teraz wracając do oryginalnego pytania...

Czy kod DLL, musi być napisany w C++\CLI, czy może być w natywnym C++?

Może być natywny C++, może być C++/CLI. w przypadku natywnego będziesz musiał eksportować funkcje globalne, które w C# załadujesz za pomocą DllImport. w przypadku C++/CLI możesz tworzyć normalne klasy zarządzane i używać ich pod C#.

0

Właśnie stworzyłem takie okienko w C++\CLI według twoich wskazań i działa, tak jak powinno. Wielkie dzięki!

Czyli nie ma takiej opcji że napisane prze zemnie biblioteki klas w natywnym C++ nie będą działać w C#, ani w C++\CLI (ogólnie .NET). Bardzo szkoda :( Nie ma innej drogi, aby użyć natywnego kodu? Wiem, że wyraziłeś się jasno, ale w moim przypadku przerabianie C++ na C++\CLI może być bardzo czasochłonne, tym bardziej że niektóre z moich bibliotek pisałem dość dawno temu i nie pamiętam dokładnie na czym polegał mechanizm moich implementacji. A jak wiadomo przy przerabianiu kodu na "inny język" zawsze pojawiają się jakieś "dodatkowe problemy".

I jeszcze powrócę do kwestii, czy istnieje możliwość w jakiś sposób edytowanie zawartości bieżącego okna funkcjami zawartymi w DLL, które przyjmowały by jakąś referencję do okna jako argument (np. ?System::Form)? Chodzi mi o to czy ktoś kiedyś próbował tak robić, czy przy takiej referencji będę mógł odnieść się do istniejącego obiektu na formie (np. jakiegoś Labela), o którym biblioteka DLL w momencie jej tworzenia by nie wiedziała.

0

Czyli nie ma takiej opcji że napisane prze zemnie biblioteki klas w natywnym C++ nie będą działać w C#, ani w C++\CLI (ogólnie .NET). Bardzo szkoda
Nie rozumiem o co ci w tym zdaniu chodzi. Napisałem że w C# można używać bibliotek natywnych. A co do C++/CLI to sytuacja wygląda o wiele lepiej niż w C#, patrz niżej.

moim przypadku przerabianie C++ na C++\CLI może być bardzo czasochłonne
hę? 99% kodu napisanego dla natywnego C++ skompiluje się bez problemu jako C++/CLI.
Nie trzeba praktycznie nic zmieniać. Twój kod powinien się skompilować.
A nawet jeśli nie, to nie ma problemu by w ramach jednego projektu niektóre pliki .cpp były skompilowane jako C++ a inne jako C++/CLI. wszystko się razem ładnie zlinkuje.

C++/CLI to najmniej problematyczny język jeśli chodzi o łączenie kodu natywnego z zarządzanym.

I jeszcze powrócę do kwestii, czy istnieje możliwość w jakiś sposób edytowanie zawartości bieżącego okna funkcjami zawartymi w DLL, które przyjmowały by jakąś referencję do okna jako argument
Można, ale to zły projekt. Lepiej zrobić to na eventach.

0

Ostatnie zdanie twojego pierwszego postu zrozumiałem tak: że nie można używać eksportowanych klas napisanych w natywnym C++ w kodzie C#, tylko same funkcje globalne, a jeśli chodzi o C++\CLI to obie formy będą działać: klasy + funkcje globalne.

Hehe, oczywiście zdaje sobie z tego sprawę że ogólnie C++ na C++\CLI jest najmniej problematyczne, (szukam drogi najmniejszym nakładem pracy). Jeśli chodzi o podobieństwo to są bardzo podobne, ale mimo wszystko są drobne różnice: new i gcnew; * i ^; definicje dynamicznych tablic itp. Ogólnie dość dawno nie pisałem GUI w C++\CLI, zawsze staram pisać programy w natywnym kodzie, dlatego boje się o jeszcze inne, bardziej znaczące różnice (nie jestem ekspertem od C++\CLI :P ).

OK, Dzięki za pomoc i pozdrawiam :)

0

nie można używać eksportowanych klas napisanych w natywnym C++ w kodzie C#, tylko same funkcje globalne
No to dobrze zrozumiałeś.

, a jeśli chodzi o C++\CLI to obie formy będą działać: klasy + funkcje globalne.
Klasy ale też tylko zarządzane (ref class, value class) a zwykłych class nie.
Więc samo przekompilowanie C++ na C++/CLI nie pomoże, trzeba klasy przerobić.

Jeśli chodzi o podobieństwo to są bardzo podobne, ale mimo wszystko są drobne różnice: new i gcnew; * i ^; definicje dynamicznych tablic itp.

C++ (i C++/CLI) jest bardziej upierdliwy w pisaniu od C#, bo trzeba ciągle pamiętać gdzie ma być ::, gdzie . a gdzie ->.
Jest jednak parę rzeczy lepiej zrobionych niż w C#, np. stack semantics którego nie ma w C# (zamiast tego jest using() { }).

Na dodatek designer Windows Forms wrzuca wszystko do pliku .h - razem z ciałami funkcji. Klasa dzięki temu wygląda bardziej jak w C#, ale jeśli projekt ma mieć wiele form które wzajemnie do siebie odwołują, szybko się okazuje że trzeba zrobić ścisły podział na .cpp i .h, i trzeba zrobić to ręcznie (poprzenosić ciała funkcji) a potem walczyć z designerem i poprawiać po nim bo nadal nowe metody będzie wrzucał do .h.

Pozostaje ci decyzja, czy do GUI wolisz niewygodne C++/CLI ale dostęp do klas C++, czy szybsze w kodzeniu C# z ograniczoną możliwością użycia natywnego kodu.

A może coś zupełnie innego, natywnego, np. wreszcie darmowe od dwóch tygodni MFC jeśli o samym VS2013 mówimy.

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