从C#包装C ++ DLL的问题

时间:2011-12-28 19:35:43

标签: c# c++ dll interop wrapping

我正在使用System.Runtime.InteropServices从我的C#app调用用C ++编写的几个函数。我只是遇到了一个返回数组的特定函数的问题。

我已经看到我的函数不应返回任何内容,并且应该输入指向“返回变量”的指针。但我没有成功地做到这一点。

例如,如果我在c ++中有一个函数

void func(double *y, double *x){...}

操纵数组x并返回数组y。

我在做:

-in my .h:

extern "C" __declspec(dllexport) void func(double *y,double *x);

- 我的.cpp:

__declspec(dllexport) void func(double *y,double *x){...}

-in my c#code:

static class AnyClass
  {
    [DllImport(dllPath)]
    public extern static void func(out double[] y, double[] x);

    int otherfunc
    {
      double[] x = new double[5];
      double[] y = new double[5];

      ...

      func(out y, x); 
    }
  }

但它给了我一个System.EntryPointNotFoundException。

有任何线索吗?

3 个答案:

答案 0 :(得分:3)

EntryPointNotFoundException表示在您的DLL中找不到任何名为“function”的内容。

在你的.h文件中,你称之为'func'。但在你的.cpp文件中,你称之为“功能”。由于你的.h文件是唯一声明extern "C"的地方,实际发生的是该函数是由你的DLL c ++ - 样式名称修改而不是plain-c-style导出的。因此,当C#寻找普通c风格的“函数”时,它无法找到它。

答案 1 :(得分:1)

我认为,您还必须在.cpp文件中指定extern "C"。如果没有,您最终可能会得到两个不同的函数func,只有声明并且没有定义具有正确链接的函数。

注意: Afair extern "C"链接还指定了如何在DLL文件中命名函数。对于C ++函数,有些预先考虑。后缀被添加到与签名相关的名称(即参数和返回类型)。这是必要的,因为您可以在C ++中重载函数。因此,如果未指定extern "C",则DLL中的函数名称不同,因此托管代码无法找到它们。

答案 2 :(得分:1)

EntryPointNotFoundException表示运行时无法在DLL中找到指定的函数名。

可能的原因是

  • 您拼错了DLL或程序中的函数名称
  • 您没有停用名称修改(extern "C"

第一个原因很容易找到,只需仔细检查所有名称并确保它们真的相同。如果由于某种原因您无法更改DLL,但又喜欢与C#不同的名称,则可以使用DllImportAttribute.EntryPoint属性指向其他名称的函数。

第二个更难以获得。为了诊断问题,我建议你使用Dependency Walker来查看编译后的DLL中真正发生的事情。使用该工具,您可以看到函数名称,以及它们是否为C ++'ified。

您已尝试使用extern "C"确保函数名称不受名称修改的影响。也许您没有在.cpp文件中包含.h文件,因此编译器根本看不到extern "C"