Почему не удается вызвать функции libsass с помощью.NET P/Invoke?
Я скомпилировал libsass 3.3.6 в DLL с VS 2015, используя включенные файлы решения. Выполнение приведенного ниже кода приводит к аварийному завершению работы программы без вывода данных.
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 при сбое дает мне следующее исключение: необработанное исключение 0x771A9841 (ntdll.dll) в Sass.Cli.exe: 0xC0000374: повреждена куча (параметры: 0x771DC8D0).
Это то, что можно исправить или что я упустил из виду? Или это просто тот случай, когда библиотеки libsass в настоящее время не работают?
1 ответ
Когда string
используется как тип возвращаемого значения, тогда фреймворк предполагает, что он был выделен путем вызова CoTaskMemAlloc
, Затем он копирует содержимое строки и освобождение, вызывая CoTaskMemFree
, Это объяснение вашей ошибки.
Решите это, изменив возвращаемое значение на IntPtr
и получать содержимое строки с Marshal.PtrToStringAnsi
, Вам не нужно иметь дело с чем-либо, так как эта строка версии будет статической.
Я не могу сказать, что такое соглашение о вызовах. Вы должны проверить код и документы, чтобы узнать. Тем не менее, эта функция настолько проста, что она ведет себя одинаково как для cdecl, так и для stdcall, поэтому не может объяснить ошибку. Тем не менее, вам нужно будет сделать это правильно для остальной части библиотеки.
Обратите внимание, что я думаю, здесь немного. Вы не предоставили полную информацию. Вы должны проконсультироваться с кодом и документами, чтобы дважды проверить мои догадки.