【问题标题】:Defining extern "C" function in C#在 C# 中定义外部“C”函数
【发布时间】:2011-04-30 23:39:29
【问题描述】:

我有一个用 C# 编写的 ActiveX 控件,并在 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# 编程经验的人可以验证我所做的翻译是否正确,那可能会有所帮助。

【问题讨论】:

    标签: c# activex extern dllexport codesys


    【解决方案1】:

    你说 CoDeSys 是 ActiveX 兼容的;你试过使用 COM 互操作吗?

    【讨论】:

    • 我相信是的。您是指选中项目中的复选框Properties > Build > Register for COM interop
    【解决方案2】:

    似乎有 3 个主要选项;第一个是设置 COM 互操作,您可以在其中使用 COM 实例化您的 C# 控件/类。我敢肯定,如果您进行一些搜索,您可以找到更多相关信息。

    第二个选项是让您的 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

    可能还有其他选择;这些是我所知道的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多