请提供一个WPF调用.net AOT dll的正确示例

William Liu 511 信誉分
2024-11-14T02:42:23.5166667+00:00

一个.net8/9的library, 暴露出一个函数功能为:接受一个指定长度,返回这个长度的字符'a'拼接的字符串. 将这个library通过aot编译成dll供WPF调用.

一个wpf的空模板项目,主页面上有一个按钮,点击后通过pinvoke调用上述的AOT dll获得长度为1万的字符串,并输出获得字符串的长度.

谢谢!

.NET
.NET
基于 .NET 软件框架的 Microsoft 技术。
71 个问题
Windows Presentation Foundation
Windows Presentation Foundation
.NET Framework 的一部分,它提供统一的编程模型,用于在 Windows 上构建业务线桌面应用程序。
131 个问题
0 个注释 无注释
{count} 票

接受的答案
  1. Hongrui Yu-MSFT 3,645 信誉分 Microsoft 供应商
    2024-11-14T10:08:32.0433333+00:00

    你好,@William Liu。欢迎来到 Microsoft 问答。

    这种使用方式似乎并不主流。你可以尝试下面的方式来使用。

    创建Class Library

    创建一个名为ClassLibrary1Class Library,在其下面创建一个名为StringGenerator的类,添加下面的代码。

    public class StringGenerator
    {
        [UnmanagedCallersOnly(EntryPoint = "GenerateString")]
        public static IntPtr GenerateString(int length)
        {
            string result = new string('a', length);
            return Marshal.StringToHGlobalAnsi(result);
        }
    }
    

    点击ClassLibrary1 ,在<PropertyGroup>中添加<PublishAot>true</PublishAot>。打开Terminal(View->Terminal),通过cd ClassLibrary1定位到ClassLibrary1项目中,运行下面的命令生成dll:

    dotnet publish -r win-x64 -c Release
    

    更详细的生成dll的方法你可以参考文档

    创建WPF Application

    在MainWindow.xaml中按如下调整代码

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="7*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <TextBox x:Name="MyTextBox" Grid.Row="0" Width="400" Height="300" VerticalScrollBarVisibility="Visible" TextWrapping="Wrap" ></TextBox>
            <Button Content="Click Me!" Width="200" Height="50"  Click="Button_Click" Grid.Row="1"></Button>
        </Grid>
    

    在MainWindow.xaml.cs中按如下调整代码

    public partial class MainWindow : Window
    {
        [DllImport("ClassLibrary1.dll", EntryPoint = "GenerateString", CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr GenerateString(int length);
    
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int length = 10000;
                IntPtr resultPtr = GenerateString(length);
                string result = Marshal.PtrToStringAnsi(resultPtr);
                MyTextBox.Text = "string length: " + result.Length + "\n" + "string: " + result;
                // 记得释放非托管内存
                Marshal.FreeHGlobal(resultPtr);
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message.ToString());
            }
        }
    }
    
    

    WPF项目引用dll

    对WPF项目进行右键->Rebuild

    ...ClassLibrary1\bin\Release\net8.0\win-x64\publish处的ClassLibrary1.dll复制到...WpfApp1\bin\Debug\net8.0-windows

    配置启动方式为不构建直接运行。

    Picture1

    Picture2

    以调试方式运行WPF项目

    Picture3

    运行结果

    Picture4


    如果答案是正确的,请点击“接受答案”并点赞。 如果您对此答案还有其他疑问,请点击“评论”。

    注意:如果您想接收相关电子邮件,请按照我们的文档中的步骤启用电子邮件通知 此线程的通知。

    1 个人认为此答案很有帮助。

0 个其他答案

排序依据: 非常有帮助

你的答案

问题作者可以将答案标记为“接受的答案”,这有助于用户了解已解决作者问题的答案。