How to use Reflection on a COM object?

Asked

Viewed 172 times

5

I am trying to do a Reflection in a program, however, when the time to pick up the type of the object (Which is necessary for the Reflection) is returning "System. __Comobject", and this is not useful. The method I tried was the following:

Type tipo = simObjects.GetType();

The same feedback happens when I try with the typeof() method; I researched and found the following method:

Type tipo = Microsoft.VisualBasic.Information.TypeName(simObjects);

It returns the right type, but in string format, (it from the error in the above code "Cannot implicit Convert "String" to "System.Type", but I swapped Type for String and it returned the type name) some genius can tell me how I can return in Type form?

2 answers

4

Is not possible.

System.__COMObject is a class declared as internal and all its methods are exposed by System.Runtime.InteropServices.Marshal. Therefore, this class is nothing more than a wrapper for the COM object, not having a type . Net derivative that can be obtained by the method Object.GetType().

If you want to see more about this class, I recommend taking a look at the source code:

Editing:

According to your comment, what you want then is to get RTTI from the COM library. C# does not allow this type of direct interaction with RTTI of unmanageable objects, so what to do?

1. What language your COM library was written in. It’s usually C++, but it can be written in Object Pascal as well, for example.

2. Was the COM library compiled with RTTI? If not, there is nothing that can be done but cry for the library developers to compile it with RTTI. Why? Because without RTTI, there is simply no way to re-flect an object.

3. Build a library in the same language as your COM library that does the Reflection for you. Using P/Invoke you interact with it within C#. Note that you will never have an object of the type System.Type, because this object only exists in manageable codes, which is not the case for your COM library.

Maybe just build a structure that encapsulates the std::type_info returned by operator typeid (if C++ is the language of the COM library, of course), and building the methods to get this value from your COM class is enough.

The RTTI analysis library is not complicated no (or does not seem to me at first), and needs only a few methods implemented according to your need. Compared to the other solutions I presented in the comments, it is a fraction of the complexity/effort, no doubt.

  • Do you know if there is another way to return the type of an object in the class System.__COMObject? with the second code it returned right, but in string form, and not Type, as I need..

  • 3

    Create your own empty types then, and make a string map for your types. Problem half solved (Mcgyver would be proud).

  • I need the type, in the form of Type, to do the Reflection, I create a string map with the types does not help, understood?

  • 1

    +1 by Mcgyver! It would be necessary to write an MSIL wrapper for each COM class used. This wrapper could be done in C# or MSIL. The two are as big a job as the amount of COM classes you handle and the complexity of the relationships between them. Both could be done in Runtime, including (the MSIL version is more appropriate in this case). What specific use do you want? There may be another approach to solving your bigger problem.

  • I get information from an object-shaped simulation of a program that I don’t have access to anything regarding code. This object is an instance of a class in the library of this program, which is not from the .NET. This object has several objects inside, and each object of this is different from the other, with some things in common, what I want is to take the name of the attributes of these various objects, for example, I have a valve-like object, in it I have a whole called pressure, and a float called temperature, I want to be able to print "pressure" and "temperature".

  • i managed to return the type using the method: Microsoft.VisualBasic.Information.TypeName(Objeto) However this method returns a string, to do the Reflection I need to return in the type System.Type.

  • In this case there is a solution, but it depends on one thing: language that the COM library was written. I will edit my answer.

  • I got half q by forcing the Reflexion, I forgot to reply my post, I will do this, I had not seen his last comment nor the edition of the reply...

  • Thank you very much for your answers and your time!

Show 4 more comments

2


It may not have been so clear what I wanted, but I was able to sort of resolve it by forcing reflection and it turned out there was no need to catch the guy.

foreach(PropertyDescriptor descricao in TypeDescriptor.GetProperties(ObjetoCOM))
{
    if(descricao.Name == "Nome do atributo")
    {
        foreach(PropertyDescriptor descricao2 in TypeDescriptor.GetProperties(descricao))
        {
           if(descricao.Name == "Nome do atributo")
           {
           }
        } 
    }
}

This code returns the name of the attributes, for example, if my Objetocom has the following attributes:

int idade;
string nome;
Filho filho;

and son has:

int idade;
string nome;

in the first loop, the Description. Name will be "age", "name" and "son", and in the second (assuming the condition is true with the child), "age" and "name".

Browser other questions tagged

You are not signed in. Login or sign up in order to post.