Проблема: Нужно сделать COM InterOp во время выполнения, используя отражения Передача указателей в качестве параметров? - PullRequest
0 голосов
/ 05 сентября 2010

Мне нужно сделать COM IntetrOp во время выполнения, используя отражения. Мои собственные методы COM-объекта имеют некоторые параметры, такие как указатели (DWORD *) и некоторые двойные указатели (DWORD **), а некоторые являются пользовательскими типами (например, SomeUDTType objSmeUDTType) и наоборот, его указатель (т.е. SomeUDTType * pSomeUDTType).

Теперь для динамического вызова метода у нас есть единственная опция для передачи параметров в виде массива объекта, т.е. объекта [], и статического заполнения этого массива.

Но мне нужно передать указатели, ссылки и указатели на указатели. А пока как я могу заполнять массив объектов как смешанные данные простых типов данных, указателей или ссылок и указателей на указатели.

Рабочий пример:

Собственный COM-метод:

STDMETHODIMP MyCallableMethod(DWORD *value_1,BSTR *bstrName,WESContext **a_wesContext)

Переведено tlbimp.exe (COMInterop)

UDTINIDLLib.IRuntimeCalling.MyCallableMethod(ref uint, ref string, System.IntPtr)

Теперь вызывая эти методы во время выполнения, используя отражение во время выполнения,

Смотрите здесь:

       Assembly asembly = Assembly.LoadFrom("E:\\UDTInIDL\\Debug\\UDTINIDLLib.dll");
        Type[] types = asembly.GetTypes();


        Type type = null;
        //foreach (Type oType in types)
        {
            try
            {
                type = asembly.GetType("UDTINIDLLib.RuntimeCallingClass");

            }
            catch (TypeLoadException e)
            {
                Console.WriteLine(e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            object parameters = new object[3];

            Type CustomType = asembly.GetType("UDTINIDLLib.WESContext");
            object oCustomType = Activator.CreateInstance(CustomType);
            FieldInfo fieldInfo = CustomType.GetField("MachineName",          BindingFlags.Public | BindingFlags.Instance);

            string MachineName = "ss01-cpu-102";
            string MachineIp = "127.0.0.1";
            string Certificate = "UK/78T";

            fieldInfo.SetValue(oCustomType, MachineName);
            fieldInfo.SetValue(oCustomType, MachineIp);
            fieldInfo.SetValue(oCustomType, Certificate);


            object obj = Activator.CreateInstance(type);
            MethodInfo mInfo = type.GetMethod("MyCallableMethod");
            int lengthOfParams = mInfo.GetParameters().Length;
            ParameterInfo [] oParamInfos = mInfo.GetParameters();



           object[] a_params = new object[lengthOfParams];

            int ValueType = 0;

            for(int iCount = 0; iCount<lengthOfParams; iCount++)
            {
                a_params[iCount] = ???; //Now here this array should be populated with corresponding pointers and other objects (i.e WESContext's obj)
            }

            mInfo.Invoke(obj,  a_params);   

Надеюсь, что код прояснится ... Если возникнет путаница, дайте мне знать, я соответствующим образом отредактирую свой вопрос.

Я застрял здесь, я буду признателен, если вы мне поможете. (Я запутался по поводу "динамического" ключевого слова, возможно, оно решит проблему)

Есть ли необходимость генерировать оболочки C ++ / CLI? и если в каком контексте? С уважением Усман

1 Ответ

0 голосов
/ 05 сентября 2010

Просто поместите значения ваших аргументов прямо в массив. Для параметров out / ref соответствующие элементы массива будут заменены новыми значениями, возвращаемыми функцией.

Для двойного указателя, безусловно, самый простой подход - использовать /unsafe и неуправляемые указатели, например, так (при условии, что параметр возвращает метод):

 WESContext* pWesContext; // the returned pointer will end up here
 IntPtr ppWesContext = (IntPtr)&pWesContext;

 // direct call
 MyCallableMethod(..., ppWesContext);

 // reflection
 a_params[3] = ppWesContext;
 mInfo.Invoke(obj, a_params);

После того, как вы получите указатель на структуру в pWesContext, вы можете использовать -> для доступа к членам в C #. Я не уверен, каковы правила управления памятью для вашего API; может случиться так, что в конечном итоге вам потребуется освободить эту структуру, но как именно это сделать, должно быть описано в документации к API, который вы пытаетесь вызвать.

...