Определение внешней функции "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

Там могут быть другие варианты; это те, о которых я знаю.

Другие вопросы по тегам