将 C# 中的数组和指针与 C DLL 一起使用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/741206/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:22:21  来源:igfitidea点击:

Using arrays and pointers in C# with C DLL

c#arraysdllpointersdouble

提问by

I am very new to C# (just started learning in the past week).

我对 C# 很陌生(上周才开始学习)。

I have a custom DLL written in C with the following function:

我有一个用 C 编写的自定义 DLL,具有以下功能:

DLLIMPORT void test_function (double **test)

What I am looking to do is have a pointer from C# for the array 'test'.

我想要做的是有一个来自 C# 的指针,用于数组“test”。

So, if in the DLL function I have test[0] = 450.60, test[1] = 512.99 etc. I want to be able to have that available in my C# program.

因此,如果在 DLL 函数中我有 test[0] = 450.60、test[1] = 512.99 等。我希望能够在我的 C# 程序中使用它。

In the C# program I have something similar to:

在 C# 程序中,我有类似的东西:

namespace TestUtil
{
  public class Echo
  {
    public double[] results = new double[10];
    public double[] results_cpy = new double[10];


    [DllImport("test_dll.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern unsafe void test_function(ref double[] Result);

    public unsafe void Tell()
    {
      results[0] = 0.0;
      results[1] = 0.0;

      results_cpy[0] = 0.0;
      results_cpy[1] = 0.0;

      test_function(ref results);
      results_cpy[0] = (double)results[0] + (double)results[1] ;
    }
  }
}

In the DLL's 'test_function' function I used the following:

在 DLL 的“test_function”函数中,我使用了以下内容:

*test[0] = 450.60;
*test[1] = 512.99;

Within the DLL everything was OK (I used a message box within the DLL to check the values were being applied). Back in the C# program 'results[0]' appears to be fine and I can get values from it, but 'results[1]' gives me an index out of bounds error. I know this because if I omit '+ (double)results[1]' I receive no error. Also, if I make no attempt within the DLL to modify 'test[1]' it retains the original value from C# (in my example 0.0).

在 DLL 中一切正常(我在 DLL 中使用了一个消息框来检查正在应用的值)。回到 C# 程序 'results[0]' 似乎很好,我可以从中获取值,但是 'results[1]' 给了我一个索引越界错误。我知道这一点,因为如果我省略 '+ (double)results[1]' 我不会收到任何错误。此外,如果我不在 DLL 中尝试修改“test[1]”,它会保留来自 C# 的原始值(在我的示例 0.0 中)。

Obviously I am not doing something right but this is the closest I have been able to get to having it work at all. Everything else I have tried fails miserably.

显然我没有做正确的事情,但这是我最接近让它工作的。我尝试过的其他一切都失败了。

Any help would be greatly appreciated.

任何帮助将不胜感激。

回答by Srikar Doddi

I am not sure what is going wrong, but I can certainly point you to an article that talks about p/invoke. see if this helps you.

我不确定出了什么问题,但我当然可以为您指出一篇关于 p/invoke 的文章。看看这是否对你有帮助。

http://msdn.microsoft.com/en-us/magazine/cc164123.aspx

http://msdn.microsoft.com/en-us/magazine/cc164123.aspx

回答by Dаn

I'm guessing you already know C++; if that's the case, you really should look at C++/CLI which lets you easily use managed code (.NET) from C++. The code you've shown above really isn't very C#-like (you should completely avoid unsafe).

我猜你已经知道 C++;如果是这种情况,您真的应该看看 C++/CLI,它可以让您轻松使用 C++ 中的托管代码 (.NET)。您上面显示的代码确实不是很像 C#(您应该完全避免unsafe)。

回答by JP Alioto

Similar question on SO here. Your looking at an opaque pointer, so it's likely a by-ref system InPtr as described in the other thread.

SO here上的类似问题。您正在查看一个不透明的指针,因此它可能是另一个线程中描述的 by-ref 系统 InPtr。

By the way, why not make it a double* instead of double**. That would make life easier, I think.

顺便说一句,为什么不把它变成双*而不是双**。我想,那会让生活更轻松。

回答by Simon Broadhead

There's no need for unsafe code. In fact, there's no need to pass by reference at all. If your signature looks like this:

不需要不安全的代码。事实上,根本不需要通过引用传递。如果您的签名如下所示:

void test_function (double *test)

and your import looks like this:

您的导入如下所示:

static extern void test_function(double[] Result);

Then everything should work fine. That is, assuming you only need to modify the array and not return a completely new array.

然后一切正常。也就是说,假设您只需要修改数组而不返回一个全新的数组。