一个简单的ATL com服务器:
STDMETHODIMP CMyMath::get_Version(sVersionStruct **ppVer)
{
sVersionStruct* pVer = reinterpret_cast<sVersionStruct*>(CoTaskMemAlloc(sizeof(sVersionStruct)));
if (!pVer) {
return E_OUTOFMEMORY;
} else {
*pVer = ver_;
*ppVer = pVer;
return S_OK;
}
return S_OK;
}
STDMETHODIMP CMyMath::put_Version(sVersionStruct* ver)
{
ver_ = *ver;
return S_OK;
}
idl定义:
typedef
[
uuid(72A4AA5B-6AD0-4249-B4CB-2FFB08301608)
]
struct tagVersionStruct {
int majorVersion;
int minorVersion;
} sVersionStruct;
[propget]
HRESULT Version([out, retval, ref]sVersionStruct** ver);
[propput]
HRESULT Version([in]sVersionStruct* ver)
c#.net客户端:
MathServLib.sVersionStruct ver;
ver.minorVersion = 1;
ver.majorVersion = 3;
math.set_Version(ver);
ver.minorVersion = 0;
ver.majorVersion = 0;
IntPtr ptr = math.get_Version();
int i = Marshal.ReadInt32(ptr); // RETURN RIGHT VALUE 3
Marshal.PtrToStructure(ptr, ver);
最后一行返回异常:
An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll. This structure is not value type.
由于Marshal.ReadInt32(ptr)
可以返回正确的值3
,为什么不能将IntPtr转换为struct?
PS:来自ILSpy的sVersionStruct:
namespace MathServLib
{
[Guid("72A4AA5B-6AD0-4249-B4CB-2FFB08301608")]
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct sVersionStruct
{
public int majorVersion;
public int minorVersion;
}
}
答案 0 :(得分:10)
您应该调用期望类型而不是对象的PtrToStructure的重载。导致错误的原因可能是:
var ver = Marshal.PtrToStructure(ptr, typeof(MathServLib.sVersionStruct));