首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#反射与COM对象不一致

C#反射与COM对象不一致
EN

Stack Overflow用户
提问于 2016-08-28 16:17:58
回答 1查看 158关注 0票数 0

在过去的几天里,我阅读了我能找到的关于COM对象上的C#反射的所有内容,尝试了许多代码实验,并分析了示例代码以试图提高我的理解,现在我被迫承认我知道的还不够多,所以我向社区请求帮助。

我需要能够访问和更新包装为System._COM对象的后期绑定COM对象的属性。

我尝试了所有的标准引用,但都没有成功,我使用了IDispatch,但我不喜欢使用相关的指针,所以我希望我在正常的界面中遗漏了一些非常简单的东西。我在MSDN上找到了一些关于如何做我需要的东西的论文,但是所有的例子都是用C++写的,我不能理解。

如果有人能解释一下为什么以下简单的C#代码不能像预期的那样工作,那将是非常有帮助的:

代码语言:javascript
复制
            try
        {
            // late binding:
            // localCB is a COM object (System._COMObject) created by Activator.CreateInstance() from 
            // the ProgID of a registered COM .DLL. 
            // 
            // The original .DLL has a string PROPERTY called 
            // "TESTEXTERNAL1". localCB has an IDispatch Interface.  The original COM .DLL has a separate Typelib,
            // and, although I did not register the typelib separately, I can see from OLEView on the COM object
            // that  the GUID for the typelib is included in it.

            // Here's the code that is puzzling me...
             var vv = localCB.GetType().InvokeMember("TESTEXTERNAL1", BindingFlags.GetProperty, 
                  null, localCB, null);
            string rt = vv.ToString();
            // works exactly as expected and returns the value of TESTEXTERNAL1 -  OK.

            // now try and update the SAME PROPERTY, on the SAME COM object...
            Parameters = new Object[1];
            Parameters[0] = "Hello, World!";
            localCB.GetType().InvokeMember("TESTEXTERNAL1", BindingFlags.SetProperty, 
                  null, localCB, Parameters);
            // throws an (inner) exception: HRESULT 0x8002003 DISP_E_MEMBERNOTFOUND !!!

        }
        catch (Exception xa)
        {
            string xam = xa.Message;
        }

期望已经找到并提供属性的对象能够更新相同的属性,这是不合理的吗?有没有什么我不知道的“替代更新”策略?

非常感谢你的帮助,

皮特。

更新:

为了回应乔恩的请求,这里有一些Oleview的片段:(我不得不使用图片,因为Oleview不允许我剪切和粘贴,对不起……)

OleView of the COM .DLL

OLEView typelib view

Jon,我想你已经正确地认识到问题出在setter方法上。DLL是用Fujitsu COBOL编写的,它为标识为属性的字段提供了一个“幕后”GET和SET。从C#或COBOL语言访问COM组件时,它工作得很好,但是,正如您所看到的,当我尝试使用反射访问它时,它就不能工作了。因为我不熟悉反射的使用,我怀疑我的语法是否正确,所以我试图使SET尽可能接近GET。我认为我需要在COBOL中生成自己的SET方法(针对每个属性),然后将我的"BindingFlags.SetProperty“更改为"BindingFlags.InvokeMember”。(我在BindingFlags上做了一些准备工作,发现如果指定"SetProperty“,它会自动暗示您提到的其他两个标志。)

我认为所有问题的关键在于认识到问题出在Fujitsu *COM Class SET上,这需要您有经验的眼睛才能看到。非常感谢。如果您在看完OLEView后有任何其他意见,或者可以建议任何替代方法来设置属性,我将非常感兴趣。(我并不希望为每个属性都生成SETter方法;这有点像蛮力……:-))

再次感谢,

皮特。

EN

回答 1

Stack Overflow用户

发布于 2016-08-30 07:32:06

汉斯是对的。问题出在setter方法上。我已经编写了代码来为每个属性生成一个setter,回到原始的COBOL COM组件中。它并不像我想象的那样乏味或丑陋(每个属性大约有7行COBOL代码),现在一切都很好。非常感谢社区,特别是Hans Passant的支持。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39189291

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档