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
Post a Comment