为什么使用 .NET P/Invoke 调用 libsass 函数会失败?

Why does calling libsass functions with .NET P/Invoke fail?

我编译了libsass 3.3.6 into a DLL with VS 2015 using the included solution files。 运行 下面的代码导致程序立即崩溃,没有任何输出。

using System;
using System.Runtime.InteropServices;

namespace Sass.Cli {
static class Sass {
    [DllImport(@"C:\...\libsass\win\bin\libsass.dll")]
        public static extern String libsass_version();
    }
    class Program {
        static void Main(string[] args) {
            Console.WriteLine(Sass.libsass_version());
        }
    }
}

调用函数的源位于 sass.cpp:61

const char* ADDCALL libsass_version(void)

DLL 和上面的代码都是为 x86 编译的。 运行 崩溃时的 VS 调试器给我以下异常:Sass.Cli.exe 中 0x771A9841 (ntdll.dll) 处未处理的异常:0xC0000374:堆已损坏(参数:0x771DC8D0 ).

这是可以修复还是我忽略的问题?或者只是 libsass DLL 当前不工作的情况?

string 用作 return 类型时,框架假定它是通过调用 CoTaskMemAlloc 分配的。然后它通过调用 CoTaskMemFree 复制字符串的内容并解除分配。这就是你的错误的解释。

将return的值改为IntPtr,用Marshal.PtrToStringAnsi获取字符串内容即可解决。你不需要处理定位的任何东西,因为这个版本字符串是静态的。

我不知道调用约定是什么。您应该检查代码和文档以找出答案。不过,此函数非常简单,以至于它对 cdecl 和 stdcall 的行为方式相同,因此无法解释错误。尽管如此,您仍需要为图书馆的其余部分做好准备。

请注意,我在这里猜测了一点。您没有提供完整的详细信息。您应该查阅代码和文档以仔细检查我的猜测。