[英]C++ SAFEARRAY has invalid data when returned from c# COM dll
i try to get data ( in form of a class/struct array ) from ac# dll in c++. 我尝试从c ++中的ac#dll获取数据(以类/结构数组的形式)。 i tried to work with the safearray helper function but all data i recived is invalid....
我试图使用safearray辅助函数,但我收到的所有数据均无效。...
while debugging everything works/looks perfect untill i reach the point to recive data that was generated in the dll ( only the SAFEARRAY* looks invalid ) , so maybe it is a problem with the communication between C++ application and the c# COM dll VS SAFEARRAY Debug/Auto Window VS DownloadList Debug/Auto Window 在调试时一切正常/看起来很完美,直到我到达dll中生成的接收数据为止(只有SAFEARRAY *看起来无效),所以C ++应用程序与c#COM dll VS SAFEARRAY Debug之间的通信可能有问题/自动窗口 VS DownloadList调试/自动窗口
here is a code example : C# 这是一个代码示例:C#
// data class
public class Download
{
public string Target;
public string Data;
public int Port;
}
// function called from outside dll
public Download[] GetData()
{
[...]
return DownloadList.ToArray(); // List<Download>
}
C++ C ++
#import "[...]/MSSQL_Lib.tlb"
// pDB is a class instance which contain the GetData func
[...]
SAFEARRAY* Data = pDB->GetData();
if( Data != nullptr )
{
// print varian type info from result
SafeArrayLock( Data );
VARIANT* ValueArray = (VARIANT*)Data->pvData;
long Lower = 0, Upper = 0;
SafeArrayGetLBound( Data, 1, &Lower );
SafeArrayGetUBound( Data, 1, &Upper );
for( long i = 0; i <= ( 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 also tried to marshal the c# class : 我也试图封送C#类:
[StructLayout(LayoutKind.Sequential)]
public class Download
{
[MarshalAs(UnmanagedType.BStr)]
public string Target;
[MarshalAs(UnmanagedType.BStr)]
public string Data;
public int Port;
}
but same result. 但结果相同。 with marshal i get this warning : "Type library exporter warning processing '[...].Download, [...]'. Warning: The reference type had sequential or explicit layout, and so was exported as a struct."
与marshal在一起时,我得到以下警告:“类型库导出程序警告处理'[...]。Download,[...]'。警告:引用类型具有顺序或显式布局,因此已导出为结构。” but i guess it should not result in completly invalid returned data
但我猜它不应该导致完全无效的返回数据
print results looks like : 打印结果如下:
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 they change every run a little bit. 但它们会稍微改变每次运行。
So i hope anyone could help me and find the detail i missed^^ thx for reading and feel free to ask for more details 因此,我希望有人能帮助我,找到我错过的细节^^ thx,以供阅读,并随时要求提供更多细节
Your array is not an array of VARIANT but an array of IUnknown* (a call to SafeArrayGetVartype would have told you that). 您的数组不是VARIANT的数组,而是IUnknown *的数组(对SafeArrayGetVartype的调用将告诉您)。 You'll have to change your code for something like this:
您必须为以下代码更改代码:
SAFEARRAY *psa = pDB->GetData();
if (psa)
{
SafeArrayLock(psa);
LONG lb;
LONG ub;
SafeArrayGetLBound(psa, 1, &lb);
SafeArrayGetUBound(psa, 1, &ub);
for (int i = lb; i <= ub; i++)
{
_DownloadPtr download(((IUnknown**)psa->pvData)[i]);
wprintf(L"%s\n", (LPWSTR)download->GetTarget());
}
SafeArrayUnlock(psa);
}
Note it means your Download class must also be marked as [ComVisible(true)]
, and the fields be transformed into public properties. 请注意,这意味着您的Download类也必须标记为
[ComVisible(true)]
,并且这些字段将转换为公共属性。 Because you need an IUnknown interface in this example (to see methods such as GetTarget() automatically added to the generated C++ code), I also suggest you add a [ClassInterface(ClassInterfaceType.AutoDual)]
attribute to it. 因为在此示例中您需要IUnknown接口(以查看诸如GetTarget()之类的方法自动添加到生成的C ++代码中),所以我还建议您向其添加
[ClassInterface(ClassInterfaceType.AutoDual)]
属性。
If you do want array of VARIANTs (why would you?), then you'll have to use object[]
instead of typed objects.arrays. 如果确实要使用VARIANT数组(为什么?),则必须使用
object[]
而不是键入的objects.arrays。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.