【问题标题】:P/Invoke problem (unbalanced stack)P/Invoke 问题(堆栈不平衡)
【发布时间】:2011-03-19 01:44:08
【问题描述】:

我正在尝试使用 P/Invoke 为原生 c++ .dll 制作包装器。

.dll 的源代码指定了以下入口点:

// .h-file
CHROMAPRINT_API ChromaprintContext *chromaprint_new(int algorithm);

以及方法实现:

// .cpp-file
ChromaprintContext *chromaprint_new(int algorithm)
{
    ChromaprintContextPrivate *ctx = new ChromaprintContextPrivate();
    ctx->algorithm = algorithm;
    ctx->fingerprinter = new Fingerprinter(CreateFingerprinterConfiguration(algorithm));
    return (ChromaprintContext *)ctx;
}

ChromaprintContextPrivate 类型是一个结构体:

>// .cpp-file
struct ChromaprintContextPrivate {
    int algorithm;
    Fingerprinter *fingerprinter;
    vector<int32_t> fingerprint;
};

我的 C# 包装代码:

// .cs-file
[System.Runtime.InteropServices.DllImportAttribute(
  "libchromaprint.dll", 
  EntryPoint = "chromaprint_new")]
private static extern System.IntPtr chromaprint_new(int algorithm);

public static IntPtr Chromaprint_New(ChromaprintAlgorithm algorithm)
{
    // Hardcoded parameter for testing
    return chromaprint_new(0); // (int)algorithm
}

调用 IntPtr ptr = Chromaprint_New(0); 会引发以下 MDA 异常:
调用 PInvoke function 'MyProject.ChromaprintWrapper!'MyProject.ChromaprintWrapper.LibChromaPrint::chromaprint_new' 使堆栈失衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。

所以我明白问题出在哪里(堆栈上的条目数不是预期的)。我假设方法参数int algorithm 没问题。我不确定返回类型。应该是结构体而不是指针?

我通过P/Invoke Interop Assistant 运行.h 文件获得了上面的C# 代码。返回类型是否错误?应该是什么?

vector&lt;int32_t&gt; fingerprint; 的 C# 表示形式是什么?
(参见上面的ChromaprintContextPrivate 结构。)

【问题讨论】:

    标签: c# c++ pinvoke


    【解决方案1】:

    您很可能需要指定调用约定。

    尝试以下方法:

    [System.Runtime.InteropServices.DllImportAttribute("libchromaprint.dll", 
         EntryPoint = "chromaprint_new",
         CallingConvention=CallingConvention.Cdecl)]
    

    默认情况下,这使用Winapi(实际上是 StdCall)来更容易调用 Windows API,但这通常不是大多数 C++ 库的默认设置。

    【讨论】:

      【解决方案2】:

      这是因为参数的实际传递方式,调用约定

      试试

      [DllImport("libchromaprint.dll", CallingConvention = CallingConvention.Cdecl)]
      private static extern IntPtr chromaprint_new(int algorithm);
      

      【讨论】:

        【解决方案3】:

        您需要在 dllimport 属性上声明 cdecl 调用约定。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-03-13
          • 2016-05-06
          • 1970-01-01
          • 2011-05-22
          • 1970-01-01
          • 2014-01-10
          • 1970-01-01
          相关资源
          最近更新 更多