gpt4 book ai didi

c# - 将 C# 结构编码为 C++ VARIANT

转载 作者:太空宇宙 更新时间:2023-11-04 14:00:01 24 4
gpt4 key购买 nike

首先,我对 COM 技术不是很熟悉,这是我第一次使用它,所以请多多包涵。我正在尝试从 C# 调用 COM 对象函数。

这是 idl 文件中的接口(interface):

[id(6), helpstring("vConnectInfo=ConnectInfoType")] 
HRESULT ConnectTarget([in,out] VARIANT* vConnectInfo);

这是我运行 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;

最佳答案

使用这个类 http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.variantwrapper%28v=vs.110%29.aspx包装它,然后调用所需的方法。

你能发布“ConnectInfoType”类型的 C++ 源代码吗?

关于c# - 将 C# 结构编码为 C++ VARIANT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19710072/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com