【问题标题】:COM Interop throwing EEMessageException when invoking managed DLL调用托管 DLL 时 COM 互操作引发 EEMessageException
【发布时间】:2011-07-05 22:07:35
【问题描述】:

向我证明了一个噩梦般的 COM 互操作。我有一个包含 WPF 窗口的简单托管 DLL。我有一个简单的 ViewController 类,它最终会启动这个窗口,但现在有一个什么都不做的空方法。

我为这个托管 DLL 创建了一个托管包装器,它公开了一个为 COM 互操作注册的接口。我可以调用我的托管包装器 OK。我可以在我的托管包装 DLL 的入口点显示一个 MessageBox。但是,如果我尝试在要包装的 DLL 中对该 ViewController 类调用任何方法,我会得到:

MfcVSApp1.exe 中 0x7c812aeb (kernel32.dll) 处的第一次机会异常:Microsoft C++ 异常:内存位置 0x0012cb30 处的 EEMessageException..

显然昨天一切正常。现在一些代码:

我的包装实体:

[Guid("83C799E0-9808-40c2-A1AB-80BCB77A3B18")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    [ComVisible(true)]
    public interface IMaryln
    {
        void GetEphemeris(DateTime date, double latitude, double longitude);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="date"></param>
        /// <param name="latitude"></param>
        /// <param name="longitude"></param>
        void GetEphemeris1(Int64 millSecsSince1970, double latitude, double longitude);
    }

 [Guid("144DB386-D8EF-41a8-B9B1-57EE8A64600C")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("ManagedProxy.Maryln")]
    [ComVisible(true)]
    public class Maryln : IMaryln
    {
        #region IMaryln Members

        public Maryln()
        {
            System.Diagnostics.Debugger.Launch();
        }

        public void GetEphemeris(DateTime date, double latitude, double longitude)
        {
            //new EphemerisViewController().GetEphemeris(date, latitude, longitude);
        }

        public void GetEphemeris1(Int64 nanoSecsSince1970, double latitude, double longitude)
        {
            // This method does not throw.  However, it will not be executed
            // if any method in EphemerisViewController is called.
            MessageBox.Show("Called from c++" + nanoSecsSince1970.ToString());


            try
            {
                //new Maryln().Test();    // this will not throw
                new EphemerisViewController().GetString();   // this will 
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }                              
        }

        public void Test()
        {
            MessageBox.Show("maryln test");
        }

        #endregion
    }

托管包装 DLL 引用的托管 DLL 包含一个 UserControl 和这个 ViewController:

public class EphemerisViewController
    {      
        public EphemerisViewController()
        {          
        }                 

        public void GetString()
        {
            MessageBox.Show("me");
        }

    }

这个 DLL 也注册了 COM 互操作,但后来我取消选中该选项,因为它没有帮助。大师们在船上,我在这里需要帮助。这已经花费了两个工作日,我从开始的地方退了 3 步。昨天一切正常。

加法

本机客户端正在使用我的包装器,如下所示:

void CMfcVSApp1Doc::LaunchEphemrisDialog()
{   
    HRESULT hr;
    CoInitialize(NULL);
    try 
    {               
        ManagedProxy::IMarylnPtr maryln(__uuidof(ManagedProxy::Maryln));    
        LONG64 time = 1309897499216000000;
        hr = maryln->GetEphemeris1(time, 0, 0);
    }
    catch(...)
    {

    }
}

另外,我已经多次清理和重建解决方案,但没有运气。

【问题讨论】:

    标签: com interop


    【解决方案1】:

    不知道这里可能发生了什么,但我决定放弃这个包装 DLL 并从头开始创建一个新的。我没有更改我包装的 C# 项目,只是为了查看这两个项目中的哪一个导致了问题。仅凭这一行为,我就可以调试被包装的 C# 项目中公开的每个 API。使用 Hans P 建议的项目调试技术,我能够进一步调试我的包装 DLL。看到管理异常,我松了一口气。绝对是向前迈出的一步。

    事实证明,对 EphemerisViewController 中包装 API 的每次调用都会引发无法找到依赖项的管理异常(定位的程序集清单与加载的程序集不匹配....blah..blah.)。我们都知道是什么原因造成的。

    在清除程序集引用从而消除上述错误后,我可以再次调用我的托管 DLL。一方面浪费了一天。另一方面学到了很多。为什么原始包装器停止工作超出了我的理解,但我很高兴放手。它一直是命名空间损坏和 DLL 加载问题的组合,但谁知道呢。

    我正准备放弃 COM 互操作并潜入 MFC,但男孩,我很高兴我坚持自己的立场。就我而言,与 C# 相比,C++ 开发很糟糕。例如,仅能够在 C# 中捕获一般异常,与我们在 C++ 中使用的 catch(...) 等价物相对应,这是一个很大的好处。所有用于执行简单转换的疯狂 C++ 语法和令人头疼的例程都让我头晕目眩。更不用说智能感知了,哦智能感知。使用过期的虚拟助手许可证,每天都提醒我它处于休眠状态,并且公司预算紧张,我将坚持使用 C# 一段时间,也许在完成所有这些工作后,我会考虑研究 C++ 库(如 Boost),以防万一。但是男孩,我很高兴回到 .NET。

    我在这里学到的教训是:使用 COM 互操作,您必须密切关注细节!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-22
      • 2014-02-15
      • 1970-01-01
      • 2012-01-03
      • 1970-01-01
      • 2012-07-19
      • 1970-01-01
      • 2012-07-10
      相关资源
      最近更新 更多