我在代码(C#)中使用了非托管库(用C++编写)。该库提供的所有方法都是静态的。我使用P / Invoke与库进行通信。库的工作方式如下:

  • 在调用所有其他方法之前,需要调用一个初始化方法(这需要一个参数,并且该参数只能在初始化期间设置)。
  • 有一个设置方法可以更改库的不同设置,如果需要更改库的工作方式,则需要运行此方法(更像是微调库)。可以随时更改设置。
  • 有一种方法,该方法接受一个数字数组,然后返回另一个数组。我们将其称为中间操作。此操作需要一段时间,因此我想将其缓存并防止每次进行计算。
  • 前一个方法(中间操作)返回的数组是创建结果的最后一个方法的输入。我们称其为主操作

  • 我通常想拥有该库的不同实例,一个实例的设置为,另一个实例的设置为B 。由于库是静态的,所以不能。

    如何将此库包装在实例类中?大概,类的每个实例都需要在内存中加载该库的新实例(因为该库本身的每个实例都是静态的,并且在一个库实例中不能有两个不同的设置)。

    除了重新编写库(因为我对它的编写方式没有任何控制权)以外,是否有其他解决方法?

    我真的很希望能够处理对操作方法的并行调用。

    最佳答案

    这是问题注释中所描述内容的示例实现:

    public class Library
    {
        private static class Native
        {
            [DllImport("foobar.dll")]
            public static extern void Initialize();
    
            [DllImport("foobar.dll")]
            public static extern void Settings(int param1, string param2);
    
            [DllImport("foobar.dll")]
            public static extern float[] Intermediate(float[] input);
    
            [DllImport("foobar.dll")]
            public static extern void MainMethod(float[] main);
        }
    
        private static readonly object sync = new object();
    
        private int param1;
        private string param2;
    
        static Library()
        {
            Native.Initialize();
        }
    
    
        public void Settings(int param1, string param2)
        {
            this.param1 = param1;
            this.param2 = param2;
        }
    
        public float[] Intermediate(float[] input)
        {
            lock (sync)
            {
                Native.Settings(param1, param2);
                return Native.Intermediate(input);
            }
        }
    
        public void MainMethod(float[] input)
        {
            lock (sync)
            {
                Native.Settings(param1, param2);
                Native.MainMethod(input);
            }
        }
    }
    

    最重要的事情
  • 设置不会立即调用“真实”设置,而是存储值
  • 调用Intermediate和MainMethod时,它们将应用先前存储的设置
  • 两个调用都在静态对象上同步,以避免对在不同线程上运行的Library的不同实例的调用造成干扰。
  • 10-07 12:47
    查看更多