簡體   English   中英

如何將包含UDT的SAFEARRAY的IDL結構編組為托管代碼

[英]How to marshal IDL struct containing SAFEARRAY of UDT to managed code

我有一個使用此IDL代碼定義的COM庫:

struct T_GPSParamsMap
{
  BSTR  Key;
  BSTR  Value;    
}T_GPSParamsMap;


struct T_FwClient
{
  BSTR                      Alias;
  SMSFilterActionEnum       Action;
  BSTR                      Text;
  int                       ToCall;
  int                       ToState;
  SAFEARRAY(T_GPSParamsMap) GpsData;
} T_FwClient;


struct T_SMSAction
{
  int                       ActionID;
  SMSFilterActionEnum       Action;
  BSTR                      Text;
  BSTR                      Folder;
  BSTR                      DestAddress;
  int                       ToCall;
  int                       ToState;
  SAFEARRAY(T_GPSParamsMap) GpsData;

  VARIANT_BOOL          forwardToNotListed;
  SAFEARRAY(T_FwClient) FwClients;

} T_SMSAction;

[
object,
uuid(F7942BCA-5122-46BB-94DB-89F5071842E4),
dual,
oleautomation,
nonextensible,
helpstring("ISMSFilter Interface"),
pointer_default(unique)
]
interface ISMSFilterWrapper : IDispatch{
  [id(1), helpstring("method GetFilterResult")] 
  HRESULT Init([in] BSTR schema_file_path, [out, retval] long* pVal);

  [id(2), helpstring("method GetFilterResult")] 
  HRESULT ApplyFilter([in] T_SMS* sms, [out, retval] long* pVal);

  [id(3), helpstring("method GetFilterResult")] 
  HRESULT GetFilterResult([in, out] T_SMSAction* ret_val, [out, retval] long* pVal);
};

現在,我以這種方式在c#中使用它:

SMSFilterLib.T_SMS smsFilter = new SMSFilterLib.T_SMS();
SMSFilterLib.T_SMSAction smsRule = new SMSFilterLib.T_SMSAction();

smsFilter.CalledParty = Convert.ToString(RadioID);
smsFilter.CallingParty = "1";
smsFilter.Text = Text;

m_smsFilter.ApplyFilter(ref smsFilter);

int RV = m_smsFilter.GetFilterResult(ref smsRule);

最后一行引發一個異常(從意大利語翻譯):

HResult = -2146233054

“ System.TypeLoadException”類型的第一次機會異常無法封送“ SMSFilterLib.T_SMSAction”類型的已歸檔GpsData:此類型不支持封送處理。

該COM庫用於舊的VB6應用程序中,並且運行良好。

我已經使用Visual Studio的標准CCW在c#中將其導入(通過引用將其添加),但也許它需要具有自定義CCW。

有人可以給我一些使用建議嗎?

問候,丹妮爾

而是使用Visual Studio“添加引用Windows”添加COM引用,而是使用tlbimp.exe創建一個互操作程序集

通過Visual Studio添加COM庫時,它將通過tlbimp創建定義,將傳遞給/ sysarray的開關“導入SAFEARRAY作為System.Array”傳遞給它。

無需使用VS,而無需通過該開關即可手動使用tlbimp:

tlbimp.exe COM_DLL_NAME.dll /out:INTEROP_ASSEMBLY_NAME.dll

它將創建專門的類型化數組:

  [Guid("4162E179-7E99-4783-95D9-DA9A0B3BE568")]
  public struct T_SMSAction
  {
    public SMSFilterActionEnum Action;
    public int ActionID;
    public string DestAddress;
    public string Folder;
    public short forwardToNotListed;
    public T_FwClient[] FwClients;
    public T_GPSParamsMap[] GpsData;
    public string Text;
    public int ToCall;
    public int ToState;
  }

問候。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM