为什么使用 .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 的行为方式相同,因此无法解释错误。尽管如此,您仍需要为图书馆的其余部分做好准备。
请注意,我在这里猜测了一点。您没有提供完整的详细信息。您应该查阅代码和文档以仔细检查我的猜测。
我编译了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 的行为方式相同,因此无法解释错误。尽管如此,您仍需要为图书馆的其余部分做好准备。
请注意,我在这里猜测了一点。您没有提供完整的详细信息。您应该查阅代码和文档以仔细检查我的猜测。