2

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

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

我通常希望有不同的库实例,一个具有设置 A,另一个具有设置 B。由于图书馆是静态的,我不能。

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

除了重写库(因为我无法控制它的编写方式)之外,是否有解决方法?

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

4

2 回答 2

1

这是问题评论中所说内容的示例实现:

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);
        }
    }
}

最重要的事情

  • Settings 不会立即调用“真实”设置,而是存储值
  • 当调用 Intermediate 和 MainMethod 时,它们会应用之前的设置存储
  • Both calls are synchronized on a static object to avoid that calls to different instances of Library running on different threads interfere.
于 2013-02-13T11:07:15.727 回答
0

As I suggested in my comment, if palatalization is required, the only workaround I can think of is to go with a multi-process approach: wrapping each "settings" in an independent process. Of course that will make communication and data-traffic between processes the new candidate for a bottle-neck (whether you will be using WCF named pipes, Remoting, WM_COPYDATA or sockets).

于 2013-02-13T11:48:02.333 回答