Я знаю, что могу заставить это работать технически, но я хотел бы реализовать максимально чистое решение. Вот ситуация:
У меня есть управляемая библиотека, которая обертывает неуправляемую библиотеку C-стиля. Функциональность библиотеки в стиле C, которую я сейчас обертываю, выполняет некоторую обработку, включающую список строк. Клиентский код библиотеки может предоставить делегата, так что во время обработки списка, если встречается «недопустимый» сценарий, библиотека может выполнить обратный вызов клиенту через этот делегат и позволить ему выбрать стратегию для использования (сгенерировать исключение, заменить недопустимые символы и т. д.)
В идеале я хотел бы иметь весь управляемый C++, изолированный в одной функции, а затем иметь возможность вызывать отдельную функцию, которая принимает только неуправляемые параметры, чтобы весь собственный C++ и неуправляемый код были изолированы в этой одной точке. Предоставление механизма обратного вызова для этого неуправляемого кода оказалось для меня камнем преткновения.
#pragma managed
public delegate string InvalidStringFilter(int lineNumber, string text);
...
public IList<Result> DoListProcessing(IList<string> listToProcess, InvalidStringFilter filter)
{
// Managed code goes here, translate parameters etc.
}
#pragma unmanaged
// This should be the only function that actually touches the C-library directly
std::vector<NativeResult> ProcessList(std::vector<char*> list, ?? callback);
В этом фрагменте я хочу сохранить весь доступ к C-библиотеке в ProcessList, но во время обработки ему нужно будет выполнять обратные вызовы, и этот обратный вызов предоставляется в виде делегата InvalidStringFilter, который передается от какого-либо клиента моя управляемая библиотека.