Как вернуть List из c # и использовать его в vc ++ через com - PullRequest
0 голосов
/ 24 июня 2009

Как вернуть List из метода c # и Использовать возвращаемые значения List в c ++, можете ли вы дать руководство, как это сделать ??
Я иду следующим образом, мой полный сценарий:

в c # DemoLib.cs

usng System;using System.Collections.Generic;

public interface IDiscover
{
  void GetList1();
  String GetList2();
  List<string> GetList3();
};

namespace DemoLibrary

{

  class DemoLib
 {
   public void GetList1()
   {

    Console.WriteLine(" I am from Void GetList()");

   }
   public string GetList2()
   {

    Console.WriteLine(" I am from string GetList()");

    return "Stack OverFlow";

   }

   public List<string> GetList3()
   {

    List<string> li=new List<string>();

    li.Add("India");
    li.Add("America");
    li.Add("London");

     Console.WriteLine(" I am from List<string> GetList()");

    return li; 
   }

Построить успешно и создать DemoLib.dll

Я копирую DemoLib.dll в c: \ DemoLib.dll и с помощью regasm создал Demolib.tlb в c: \

Теперь в Vc ++ i Hav main ()

DemoLibMain.vc ++

#include<list>

#include<stdio.h>

void main()
{

   HRESULT Hr=CoInitialize(NULL);

  IDiscoverPtr Iptr(__uuidof(DemoLib));

   Iptr->GetList1();

  std::string str=Iptr->GetList2();

  printf("%s",str); //dispalys "null" insted of "stack overflow" but when i debugging it 

                     shows the value "stack overflow" at str.

Iptr -> (Боюсь, поскольку он не дает GetList3 ())

когда я заставил написать Iptr-> GetList3 (), он отображает ошибку как

GetList3 не является членом IDiscover;

Ответы [ 3 ]

1 голос
/ 24 июня 2009

Я сделал это, используя тип объекта c #

C # экспортируется как COM

public void GetList(ref object list)
{
  String[] dummy = { "1" };
  Array.Resize(ref dummy, 3);
  list = dummy;
}

Родной C ++

_variant_t list;
GetList(list);
const VARTYPE type (static_cast<VARTYPE>(list.vt & VT_TYPEMASK));
const bool isArray (0 != (list.vt & VT_ARRAY));
const bool isVector(0 != (list.vt & VT_VECTOR));
if(isArray) {
  SAFEARRAY* buffer = src.parray;
  ...
}

Проблема здесь в том, что SAFEARRAY не доступен для vbscript. Но это не проблема для большинства других языков.

1 голос
/ 24 июня 2009

Тот же вопрос вчера:

Как вернуть коллекцию строк из C # в C ++ через COM-взаимодействие

(Краткий ответ: список не будет включен в интерфейс COM, поскольку используется универсальный тип).

0 голосов
/ 24 июня 2009

Когда вы импортируете tlb в VC ++ и компилируете, в вашем промежуточном каталоге создается промежуточный файл с расширением .tlh (обычно это каталог отладки / выпуска в зависимости от вашей текущей конфигурации). Это своего рода прокси-файл и содержит все методы, которые вы можете вызвать. Посмотрите на этот файл, и он даст вам точный синтаксис того, что должно быть передано.

Что касается вашего метода GetList2, он возвращает простую строку, которая преобразуется в BSTR в сгенерированном tlb, поэтому вам необходимо получить возвращаемое значение в BSTR. Для GetList3, поскольку вы возвращаете массив, поэтому, скорее всего, тип возвращаемого значения в файле .tlh будет вариантом, содержащим массив BSTR. Вероятнее всего, vt варианта будет VT_ARRAY | VT_BSTR. Вы можете пройти через этот массив в варианте и получить все значения по одному.

РЕДАКТИРОВАТЬ: Как кто-то еще предположил, что это List <>, поэтому он не будет переведен в тип COM. ИМО, ваш лучший вариант - использовать ArrayList вместо List <>

Другое редактирование: я только что проверил, и ArrayList не переводится ни на один из типов автоматизации COM. В этом случае лучше всего использовать простой строковый массив, привести его к объекту и вернуть этот объект из вашего метода. Этот объект будет преобразован в вариант, содержащий SafeArray BSTR. Вам нужно будет перебрать этот защитный массив, чтобы получить ваши данные.

...