How to return List from c# and use it in vc++ thro

2020-05-03 12:55发布

问题:

How to return List from c# method and Use the List return values in c++ can u give guidance how to do it??
I going like following way my complete scenario:

in 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; 
   }

Build successfully and created DemoLib.dll

I copy the DemoLib.dll to c:\DemoLib.dll and using regasm created Demolib.tlb in c:\

Now in 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->(Afraid since it doesnot give GetList3() )

when i forced to write Iptr->GetList3() it Display the error as

GetList3 is not a member of IDiscover;

回答1:

I did it using the object type of c#

C# exported as COM

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

Native 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;
  ...
}

Problem here is that a SAFEARRAY isn't accessible by vbscript. But its no problem for most other languages.



回答2:

Same question yesterday:

How to return a collection of strings from C# to C++ via COM interop

(Short answer: List won't be included in the COM interface because it uses a generic type).



回答3:

When you import a tlb in VC++ and compile it, an intermediate file is generated with extension .tlh in your intermediate directory (normally debug/release directory depending upon your current configuration) . This is sort of a proxy file and contains all the methods that you can call. Have a look at this file and this will give you the exact syntax of what should be passed.

As far as your method GetList2 is concerned, it is returning a simple string which translates to a BSTR in the generated tlb so you need to get the return value in a BSTR. For GetList3 since you are returning an array, therefore, most probably the return type in .tlh file will be a variant containing an array of BSTRs. The vt of the variant will most probably be VT_ARRAY|VT_BSTR. You can loop-through this array in the variant and get all the values one-by-one.

EDIT: As somebody else suggested that it is List<>, therefore, it won't get translated to a COM Type. IMO, your best option is to use ArrayList instead of using List<>

Another Edit: I just checked and ArrayList does not get translated to any of the COM Automation types. In this case your best bet is to use a simple string array, cast it to object and return that object from your method. This object will be converted to a variant containing a SafeArray of BSTRs. You will need to loop-through that safearray to get your data.