首先,我對COM技術並不是很熟悉,這是我第一次使用它,因此忍受着我。 我想從C#調用一個COM對象函數。將C#結構元素編組爲C++ VARIANT
這是在IDL文件的接口:
[id(6), helpstring("vConnectInfo=ConnectInfoType")]
HRESULT ConnectTarget([in,out] VARIANT* vConnectInfo);
這是互操作接口I運行TLBIMP後得到:
void ConnectTarget(ref object vConnectInfo);
在用於目標函數的COM對象C++代碼:
STDMETHODIMP PCommunication::ConnectTarget(VARIANT* vConnectInfo)
{
if (!((vConnectInfo->vt & VT_ARRAY) && (vConnectInfo->vt & VT_BYREF)))
{
return E_INVALIDARG;
}
ConnectInfoType *pConnectInfo = (ConnectInfoType *)((*vConnectInfo->pparray)->pvData);
...
}
此COM對象在另一個進程中運行,它不在dll中。
我可以補充說COM對象也可以從另一個用C++編寫的程序中使用。在這種情況下,沒有問題,因爲在C++中創建VARIANT,並將pparray-> pvData設置爲connInfo數據結構,然後使用VARIANT作爲參數調用COM對象。
在C#中,據我瞭解,我的結構應自動編組爲VARIANT。
這兩種方法我已經使用(或實際上我已經嘗試了很多...)來調用C#這種方法:
private void method1_Click(object sender, EventArgs e)
{
pcom.PCom PCom = new pcom.PCom();
pcom.IGeneralManagementServices mgmt = (pcom.IGeneralManagementServices)PCom;
m_ci = new ConnectInfoType();
fillConnInfo(ref m_ci);
mgmt.ConnectTarget(m_ci);
}
在結構被編組與上述情形VT_UNKNOWN。這是一個簡單的例子,如果參數不是一個結構(例如,爲int工作)。
private void method4_Click(object sender, EventArgs e)
{
ConnectInfoType ci = new ConnectInfoType();
fillConnInfo(ref ci);
pcom PCom = new pcom.PCom();
pcom.IGeneralManagementServices mgmt = (pcom.IGeneralManagementServices)PCom;
ParameterModifier[] pms = new ParameterModifier[1];
ParameterModifier pm = new ParameterModifier(1);
pm[0] = true;
pms[0] = pm;
object[] param = new object[1];
param[0] = ci;
object[] args = new object[1];
args[0] = param;
mgmt.GetType().InvokeMember("ConnectTarget", BindingFlags.InvokeMethod, null, mgmt, args, pms, null, null);
}
在這種情況下,它被編組爲VT_ARRAY | VT_BYREF | VT_VARIANT。問題是,當調試「目標函數」ConnectTarget時,我無法找到在SAFEARRAY結構中發送的數據(或者在內存中的任何其他地方)
我該如何處理VT_VARIANT?
關於如何獲取我的結構數據的任何想法?
更新:
的ConnectInfoType結構:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class ConnectInfoType
{
public short network;
public short nodeNumber;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 51)]
public string connTargPassWord;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string sConnectId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string sConnectPassword;
public EnuConnectType eConnectType;
public int hConnectHandle;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string sAccessPassword;
};
而且在C++中對應的結構:
typedef struct ConnectInfoType
{
short network;
short nodeNumber;
char connTargPassWord[51];
char sConnectId[8];
char sConnectPassword[16];
EnuConnectType eConnectType;
int hConnectHandle;
char sAccessPassword[8];
} ConnectInfoType;
您是否[搜索](https://www.google.com/search?q=c%23+COM+variant&oq=c%23+COM+variant&aqs=chrome..69i57j69i58j0l4.4373j0j7&sourceid=chrome&espv=210&es_sm= 93即= UTF-8)?看起來可能有些幫助。 – crashmstr
我一直在搜索整天,幾乎所有的帖子都來自搜索。並繼續搜索,謝謝。 – rdrmntn
@jortan,目前尚不清楚,你的目標是將C#中的'ConnectInfoType'數組傳遞給C++,還是隻傳遞一個'ConnectInfoType'? – Noseratio