C++ SAFEARRAY has invalid data when returned from c# COM dll -


i try data ( in form of class/struct array ) c# dll in c++. tried work safearray helper function data recived invalid....

while debugging works/looks perfect untill reach point recive data generated in dll ( safearray* looks invalid ) , maybe problem communication between c++ application , c# com dll vs safearray debug/auto window vs downloadlist debug/auto window

here code example : c#

// data class public class download {     public string target;     public string data;     public int port; }  // function called outside dll public download[] getdata() {     [...]     return downloadlist.toarray(); // list<download> } 

c++

#import "[...]/mssql_lib.tlb" // pdb class instance contain getdata func [...] safearray* data = pdb->getdata(); if( data != nullptr ) {     // print varian type info result     safearraylock( data );      variant* valuearray = (variant*)data->pvdata;     long lower = 0, upper = 0;     safearraygetlbound( data, 1, &lower );     safearraygetubound( data, 1, &upper );      for( long = 0; <= ( upper - lower ); ++i )     {         printvariant( &valuearray[i] );     }      safearrayunlock( data );     safearraydestroy( data ); } [...] // function end  void printvariant( variant* pv ) {     switch( pv->vt )     {         case vt_bstr:             wprintf( l" string : %s \n", pv->bstrval );             break;         default:             wprintf( l" unrecognized type : %d \n", pv->vt );             break;     } } 

i tried marshal c# class :

[structlayout(layoutkind.sequential)] public class download {     [marshalas(unmanagedtype.bstr)]     public string target;     [marshalas(unmanagedtype.bstr)]     public string data;     public int port; } 

but same result. marshal warning : "type library exporter warning processing '[...].download, [...]'. warning: reference type had sequential or explicit layout, , exported struct." guess should not result in completly invalid returned data

print results looks :

 unrecognized type : 65432  unrecognized type : 65048  unrecognized type : 64664  unrecognized type : 64280  unrecognized type : 1  unrecognized type : 0  unrecognized type : 0  unrecognized type : 43008  unrecognized type : 21288  unrecognized type : 1331 

but change every run little bit.

so hope me , find detail missed^^ thx reading , feel free ask more details

your array not array of variant array of iunknown* (a call safearraygetvartype have told that). you'll have change code this:

safearray *psa = pdb->getdata(); if (psa) {     safearraylock(psa);     long lb;     long ub;     safearraygetlbound(psa, 1, &lb);     safearraygetubound(psa, 1, &ub);     (int = lb; <= ub; i++)     {         _downloadptr download(((iunknown**)psa->pvdata)[i]);         wprintf(l"%s\n", (lpwstr)download->gettarget());     }     safearrayunlock(psa); } 

note means download class must marked [comvisible(true)], , fields transformed public properties. because need iunknown interface in example (to see methods such gettarget() automatically added generated c++ code), suggest add [classinterface(classinterfacetype.autodual)] attribute it.

if want array of variants (why you?), you'll have use object[] instead of typed objects.arrays.


Comments

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -