Hi!
I have IDL-file:
const byte DataStrLen = 255;
#pragma pack(1)
typedef struct
{
wchar_t fDataStr[DataStrLen];
} tSomeData;
#pragma pack()
[
object,
uuid(...),
pointer_default(unique),
local
]
interface ISomeData : IUnknown
{
tSomeData* getDataPtr();
};
I trying to reproduce it in managed c++:
const Byte DataStrLen = 255;
[ComVisible(true)]
[StructLayout(LayoutKind::Sequential, Pack = 1, CharSet =
CharSet::Unicode)]
public value struct tSomeData
{
[MarshalAs(UnmanagedType::ByValTStr, SizeConst = DataStrLen)]
String ^fDataStr;
};
[ComVisible(true)]
[Guid("...")]
[InterfaceType(ComInterfaceType::InterfaceIsIUnknow n)]
public interface class ISomeData
{
[PreserveSig]
tSomeData* getDataPtr();
};
[ComVisible(true)]
[Guid("...")]
[ClassInterface(ClassInterfaceType::None)]
public ref class SomeData : public ISomeData
{
public:
SomeData ()
{
m_tSomeData = gcnew tSomeData;
m_tSomeData->fDataStr= "ABC";
}
virtual tSomeData* getDataPtr()
{
pin_ptr pinPtr = &*m_tSomeData;
return pinPtr;
}
private:
tSomeData ^m_tSomeData;
};
After processing in tlbexp.exe I use tlb-file in test application:
#import "SomeData.tlb" no_namespace raw_interfaces_only
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = ::CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hr))
return -1;
try
{
CComPtr<ISomeDataspSomeData;
hr = ::CoCreateInstance(__uuidof(SomeData), NULL,
CLSCTX_INPROC_SERVER,
__uuidof(ISomeData),
(void**)&spSomeData);
tSomeData *pSomeData = spSomeData->getDataPtr(); // !!!
MarshalDirectiveException !!!
}
catch (...)
{
}
::CoUninitialize();
return 0;
}
When I run test following error occurred while determining how to
marshal the parameters of member 'getDataPtr' of type
'SomeData.ISomeData':
"System.Runtime.InteropServices.MarshalDirectiveEx ception: Cannot
marshal 'parameter #4294967295': Pointers cannot reference marshaled
structures. Use ByRef instead. This is most likely due to an
incompatible MarshalAs attribute on one of the parameters."
Where is error? What shall i do to implement such component?