TL; DR: CppSharp генерирует неправильный код привязки для определенной сигнатуры метода C ++. Как я могу использовать TypeMaps и или проходы, чтобы исправить это? Есть ли документация или примеры преобразований типов, которые я могу использовать?
я использую CppSharp генерировать привязки C # для OBS studio, чтобы написать плагин для него.
При генерации кода из OBS.h используется следующий генератор:
class OBSBindingsGenerator: ILibrary
{
public void Postprocess(Driver driver, ASTContext ctx)
{
}
public void Preprocess(Driver driver, ASTContext ctx)
{
}
public void Setup(Driver driver)
{
var options = driver.Options;
options.GeneratorKind = CppSharp.Generators.GeneratorKind.CSharp;
var module = options.AddModule("OBS");
module.IncludeDirs.Add(@"path\to\libobs");
module.Headers.Add("obs.h");
}
public void SetupPasses(Driver driver)
{
}
}
class Program
{
static void Main(string[] args)
{
ConsoleDriver.Run(new OBSBindingsGenerator());
}
}
Я считаю, что он генерирует:
[SuppressUnmanagedCodeSecurity]
[DllImport("OBS", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="video_format_get_parameters")]
[return: MarshalAs(UnmanagedType.I1)]
internal static extern bool VideoFormatGetParameters_0(global::OBS.VideoColorspace color_space, global::OBS.VideoRangeType range, float matrix, float min_range, float max_range);
и соответствующий публичный метод
public static bool VideoFormatGetParameters(global::OBS.VideoColorspace color_space, global::OBS.VideoRangeType range, float[] matrix, float[] min_range, float[] max_range)
{
... // Code snipped for brevity
fixed (float* __ptr4 = max_range)
{
var __arg4 = new global::System.IntPtr(__ptr4);
// See here that __arg4 is an IntPtr argument and is being passed to a float parameter
var __ret = __Internal.VideoFormatGetParameters_0(color_space, range, __arg2, __arg3, __arg4);
return __ret;
}
}
Это, очевидно, не компилируется. Определение C ++:
EXPORT bool video_format_get_parameters(enum video_colorspace color_space,
enum video_range_type range, float matrix[16],
float min_range[3], float max_range[3]);
В рукописном PInvoke это может быть исправлено разными способами (объявить структуру с нужным количеством членов с плавающей запятой или [MarshalAs(UnmanagedType.LPArray, SizeConst = 3)]
и float [] passthrough или объявить параметр PInvoke как IntPtr).
Мой вопрос: как я могу использовать CppSharp и его инструменты преобразования кода (TypeMap? Pass? What?) Для достижения любого из правильных переводов? Я мог бы исправить это как хак, но так как я взаимодействую с моими библиотеками C ++, я бы предпочел узнать правильный способ сделать это с CppSharp (научиться ловить рыбу).
Заранее спасибо!
Пожалуйста, попробуйте последнюю версию CppSharp (0.8.14+), она содержит исправления, связанные с параметрами массива.
Других решений пока нет …