WPF call data from CPP wrapper dll via CLI\CLR
1.C++ Dll project
//D:\C\CPPServiceDll\CPPServiceDll\BookNativeLib.h #pragma once #include <string> #include <vector> #include <chrono> struct Book { int id; std::string name; std::string uuid; }; class BookManager { private: static int globalId; static BookManager* instance; BookManager() {} public: static BookManager* GetInstance(); std::vector<Book> GenerateBooks(int batchSize); std::string GenerateUUID(); }; D:\C\CPPServiceDll\CPPServiceDll\BookNativeLib.cpp #include "pch.h" #include "BookNativeLib.h" int BookManager::globalId = 1; BookManager* BookManager::instance = nullptr; BookManager* BookManager::GetInstance() { if (instance == nullptr) { instance = new BookManager(); } return instance; } std::string BookManager::GenerateUUID() { char buf[64]; sprintf_s(buf, "%08X-%04X-%04X-%04X-%012X", rand(), rand() & 0xFFFF, rand() & 0xFFFF, rand() & 0xFFFF, rand() & 0xFFFFFFFFFFFF); return std::string(buf); } std::vector<Book> BookManager::GenerateBooks(int batchSize) { std::vector<Book> booksVec; booksVec.reserve(batchSize); for (int i = 1; i < batchSize+1; i++) { Book b; b.id = globalId++; b.name = "Name_" + std::to_string(b.id); b.uuid = GenerateUUID(); booksVec.push_back(b); } return booksVec; } D:\C\CPPServiceDll\CPPServiceDll\BookCLRWrapperLib.cpp #include "pch.h" #include "BookCLRWrapperLib.h" #include "BookNativeLib.h" #include <stdlib.h> #include <msclr//marshal.h> #include <msclr/marshal_cppstd.h> #using <mscorlib.dll> #using <System.dll> #using <System.Core.dll> using namespace System; using namespace System::Collections::Generic; using namespace msclr::interop; public ref struct ManagedBook { property int Id; property String^ Name; property String^ Uuid; }; public ref class BookService { private: BookManager* native; public: BookService() { native = BookManager::GetInstance(); } List<ManagedBook^>^ GetBooksList(int batchSize) { std::vector<Book> books = native->GenerateBooks(batchSize); List<ManagedBook^>^ booksList = gcnew List<ManagedBook^>(); for (auto& b : books) { ManagedBook^ mb = gcnew ManagedBook(); mb->Id = b.id; mb->Name = marshal_as<String^>(b.name); mb->Uuid = marshal_as<String^>(b.uuid); booksList->Add(mb); } return booksList; } };
2.Set properties

3.WPF and MVVM
<Window x:Class="WpfApp15.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp15" mc:Ignorable="d" Title="{Binding MainTitle}" WindowState="Maximized"> <Window.DataContext> <local:MainVM/> </Window.DataContext> <Grid> <ItemsControl ItemsSource="{Binding BooksCollection}"> <ItemsControl.Template> <ControlTemplate> <ScrollViewer CanContentScroll="True"> <VirtualizingStackPanel IsItemsHost="True" ScrollViewer.CanContentScroll="True" ScrollViewer.IsDeferredScrollingEnabled="True" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling" VirtualizingPanel.CacheLength="2,2" VirtualizingPanel.CacheLengthUnit="Item" /> </ScrollViewer> </ControlTemplate> </ItemsControl.Template> <ItemsControl.ItemTemplate> <DataTemplate> <Grid Width="{x:Static SystemParameters.FullPrimaryScreenWidth}" Height="{x:Static SystemParameters.FullPrimaryScreenHeight}"> <Grid.Resources> <Style TargetType="{x:Type TextBlock}"> <Setter Property="FontSize" Value="50"/> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="FontSize" Value="100"/> <Setter Property="Foreground" Value="Red"/> </Trigger> </Style.Triggers> </Style> </Grid.Resources> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <TextBlock Text="{Binding Id}" Grid.Row="0" Grid.Column="0"/> <TextBlock Text="{Binding Name}" Grid.Row="0" Grid.Column="1"/> <TextBlock Text="{Binding Uuid}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"/> </Grid> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </Grid> </Window> using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApp15 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } } public class MainVM : INotifyPropertyChanged { int batch_Size = 1000000; public MainVM() { Task.Run(async () => { await InitBooksCollection(); }); } private async Task InitBooksCollection(int cnt = 200000000) { BooksCollection = new ObservableCollection<ManagedBook>(); BookService service = new BookService(); int batchCount = (cnt + batch_Size - 1) / batch_Size; for (int i = 0; i < batchCount; i++) { var list = service.GetBooksList(batch_Size); var tempList = list.ToList(); list.Clear(); await Application.Current.Dispatcher.InvokeAsync(() => { foreach (var bk in tempList) { BooksCollection.Add(bk); } MainTitle = $"{DateTime.Now.ToString("yyyyMMddHHmmssffff")},loaded {BooksCollection.Count} items,{GetMem()}"; }, System.Windows.Threading.DispatcherPriority.Background); } } private string GetMem() { return $"memory {System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64 / 1024 / 1024:N2} M"; } private string mainTitle = ""; public string MainTitle { get { return mainTitle; } set { if (value != mainTitle) { mainTitle = value; OnPropertyChanged(); } } } private ObservableCollection<ManagedBook> booksCollection; public ObservableCollection<ManagedBook> BooksCollection { get { return booksCollection; } set { if (value != booksCollection) { booksCollection = value; OnPropertyChanged(); } } } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged([CallerMemberName] string propertyName = "") { var handler = PropertyChanged; handler?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } }






浙公网安备 33010602011771号