Определение внешней функции "C" в C#
У меня есть элемент управления ActiveX, написанный на C# и работающий при запуске в ActiveX-совместимой программе (CoDeSys). Проблема, с которой я столкнулся, заключается в том, что для того, чтобы CoDeSys мог взаимодействовать с элементом управления ActiveX, CoDeSys требует, чтобы dll экспортировала прототип функции:
void ExecuteActiveXCall(IUnknown* pUnk, char* pszId, char* pszParam, char* pszReturnBuffer, int nReturnBufferSize, DWORD* pdwReturnFlag);
Я посмотрел безуспешно, как экспортировать это, как вы можете в C++, как показано в этом примере:
extern "C" __declspec (dllexport) void ExecuteActiveXCall(IUnknown* pUnk, char* pszId, char* pszParam, char* pszReturnBuffer, int nReturnBufferSize, DWORD* pdwReturnFlag)
{
if (strcmp(pszId, "IWebBrowser|GoBack") == 0)
{
IUnknown* pNewUnk;
IWebBrowser* pwb;
pUnk->QueryInterface(IID_IWebBrowser, (void**) &pNewUnk);
pwb = (IWebBrowser*) pNewUnk;
if (pwb)
{
pwb->GoBack();
pwb->Release();
}
}
else if (strcmp(pszId, "IWebBrowser|GoForward") == 0)
{
IUnknown* pNewUnk;
IWebBrowser* pwb;
pUnk->QueryInterface(IID_IWebBrowser, (void**) &pNewUnk);
pwb = (IWebBrowser*) pNewUnk;
if (pwb)
{
pwb->GoForward();
pwb->Release();
}
}
}
В C# есть ключевое слово extern, но оно не позволяет вам дать определение функции (по крайней мере, я не нашел способа). После попытки этого:
extern unsafe void ExecuteActiveXCall(
[MarshalAs(UnmanagedType.IUnknown)] object pUnk,
char* pszId,
char* pszParam,
char* pszReturnBuffer,
int nReturnBufferSize,
UInt32* pdwReturnFlag)
{
}
Возникает следующая ошибка:
'AlarmsCSharp.AlarmsControl.ExecuteActiveXCall(object, char*, char*, char*, int, uint*)' cannot be extern and declare a body
Кто-нибудь пытался экспортировать функцию в C# dll?
Есть ли обходные пути? (У меня была мысль о [DllImport("AlarmsCSharp.dll")] и о вызове C# в dll C++, но я подумал, что я посмотрю, есть ли у кого-нибудь решение раньше)
Возможно, я слишком много думаю об этом и не должен экспортировать эту функцию, поскольку элемент управления ActiveX уже может взаимодействовать с кодом C#.
РЕДАКТИРОВАТЬ: я чувствую мой перевод от прототипа функции C++ к объявлению интерфейса C#. Если кто-то с большим опытом программирования на C++/C# сможет убедиться, что я сделал этот перевод правильным или неправильным, это может помочь.
2 ответа
Вы говорите, что CoDeSys совместим с ActiveX; Вы пытались использовать COM-взаимодействие?
Кажется, есть 3 основных варианта; Во-первых, настроить взаимодействие COM, где вы можете создать экземпляр своего элемента управления / класса C# с помощью COM. Я уверен, что если вы выполните поиск, вы можете найти больше информации об этом.
Второй вариант - сделать ваш модуль C++ смешанным, управляемым / неуправляемым, как описано здесь: http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/5345a27a-a614-4a74-9f6d-ea7a999ddf83/
Третий вариант - использовать "обратный PInvoke", как описано здесь: http://tigerang.blogspot.com/2008/09/reverse-pinvoke.html
Там могут быть другие варианты; это те, о которых я знаю.