У меня есть код на C++, в котором размещается clr, чтобы использовать Managed.dll, написанный на C#.Разрешить управляемый код в среде размещения для вызова неуправляемого кода
Это .net есть метод, как в следующем, что позволяет код для регистрации на уведомления о событиях:
public void Register(IMyListener listener);
интерфейс выглядит примерно так
public interface IMyListener
{
void Notify(string details);
}
я хотел бы сделать вещи в части C++ программы, вызванной событиями в мире .net. Я бы даже не возражал против создания другой управляемой dll с единственной целью сделать Managed.dll более дружественным к C++, если это необходимо.
Какие у меня варианты? Только один я уверен, что я мог бы осуществить это:
- Написать другим удалось DLL, ожидающего тех событий, очереди их и позволяет ++ доступ к исходному коду С очереди посредством опроса
Это, конечно, переходить от стиля «прерывания» к стилю «опроса» со всеми его преимуществами и недостатками и необходимостью обеспечения очереди. Можем ли мы обойтись без опроса? Могу ли я каким-то образом вызвать управляемый код и предоставить ему указатель функции в мир C++ в качестве аргумента?
Update Благодаря ответ и комментарии Стейн, я надеюсь, что я переехал немного в правильном направлении, но я думаю, главная проблема все еще открыта, как передать указатель Fn из неуправляемых земель в CLr принимал окружающую среду.
Скажем, у меня есть «Int п (INT)» тип указателя функции, которую я хочу передать в управляемом мире, вот соответствующие части:
Управляемый код (C++/CLI)
typedef int (__stdcall *native_fun)(int);
String^ MyListener::Register(native_fun & callback)
{
return "MyListener::Register(native_fun callback) called callback(9): " + callback(9);
}
Неуправляемый код
typedef int (__stdcall *native_fun)(int);
extern "C" static int __stdcall NativeFun(int i)
{
wprintf(L"Callback arrived in native fun land: %d\n", i);
return i * 3;
}
void callCLR()
{
// Setup CLR hosting environment
...
// prepare call into CLR
variant_t vtEmpty;
variant_t vtRetValue;
variant_t vtFnPtrArg((native_fun) &NativeFun);
SAFEARRAY *psaMethodArgs = SafeArrayCreateVector(VT_VARIANT, 0, 1);
LONG index = 0;
SafeArrayPutElement(psaMethodArgs, &index, &vtFnPtrArg);
...
hr = spType->InvokeMember_3(bstrMethodName, static_cast<BindingFlags>(
BindingFlags_InvokeMethod | BindingFlags_Static | BindingFlags_Public),
NULL, vtEmpty, psaMethodArgs, &vtRetValue);
if (FAILED(hr))
wprintf(L"Failed to invoke function: 0x%08lx\n", hr);
spType->InvokeMember_3
вызов приведет к a 0x80131512
результат.
Что-то кажется неправильным в том, как я передаю указатель на NativeFun в управляемый мир или как мои функции определены. При использовании параметра String^вместо fn ptr я могу успешно вызвать функцию CLR.
ваш метод CLI использует 'native_fun &', но вы передаете 'native_fun', может быть, проблема? Вы пытались использовать указатели вместо (например, 'native_fun *')? Можете ли вы присоединить отладчик (в конце концов, помещая «DebugBreak» где-нибудь) и посмотреть, правильно ли передано значение для аргумента? – stijn