A simple ATL com server:
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 definition:
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 client:
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);
The last line returns the Exception:
An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll. This structure is not value type.
Since Marshal.ReadInt32(ptr)
could return the right value 3
, why cannot convert IntPtr to struct?
PS: The sVersionStruct from ILSpy:
namespace MathServLib
{
[Guid("72A4AA5B-6AD0-4249-B4CB-2FFB08301608")]
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct sVersionStruct
{
public int majorVersion;
public int minorVersion;
}
}