在实例类中包装静态非托管库

时间:2013-02-13 10:54:42

标签: c# c++ static pinvoke

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

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

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

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

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

2 个答案:

答案 0 :(得分:0)

以下是对该问题的评论中所述内容的示例实现:

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时,他们先前应用设置存储
  • 两个调用都在静态对象上同步,以避免对在不同线程上运行的库的不同实例的调用产生干扰。

答案 1 :(得分:0)

正如我在评论中所建议的那样,如果需要进行腭化,我能想到的唯一解决方法就是采用多进程方法:将每个“设置”包装在一个独立的进程中。当然,这将使进程之间的通信和数据流量成为瓶颈的新候选者(无论您将使用WCF命名管道,远程处理,WM_COPYDATA还是套接字)。