P
Pratul
Very recently I have written a custom interop in Managed
C++. We have a C# application that uses a COM DLL as a
data provider. The COM data provider talks to other
servers for retrieving real-time data.
First of all, we used TlbImp to generate the metadata for
the COM DLL and everything worked fine except the fact
that the COM Interop was slow.
In the next phase, we decided to write a custom interop in
MC++ to improve data retrieval rates, etc. Unfortunately,
we had to make some changes in the C# application for the
custom interop to work. Consider the following two
methods (after #import by the C++ compiler):
variant_t getTag(void)
void putTag(const VARIANT& var)
When we use the default COM interop, the C# application
finds VARIANTs as System::Objects. In our C# application,
we can pass any managed object reference in the putTag()
method and later on retrieve it using the getTag()
method. It works fine - RCW does the magic to marshall a
managed object reference straight into the COM layer and
later on it can retrieve it correctly.
I could not replicate this behaviour in my custom
interop :-(. I thought Marshal::GetNativeVariantForObject
() and its counterpart should help me to marshal a managed
object reference. Say, for example:
void ManagedRecord::set_Tag(Object* tagObj /* managed
object from C# app */)
{
try
{
if (m_pRecord != NULL) // unmanaged COM
smart pointer
{
Debug::Assert(tagObj != NULL);
IntPtr intPtr;
Marshal::GetNativeVariantForObject
(tagObj, intPtr);
VARIANT* varTag =
static_cast<VARIANT*>(static_cast<void*>(intPtr));
Debug::Assert(varTag != NULL);
m_pRecord->putTag(*varTag);
C++. We have a C# application that uses a COM DLL as a
data provider. The COM data provider talks to other
servers for retrieving real-time data.
First of all, we used TlbImp to generate the metadata for
the COM DLL and everything worked fine except the fact
that the COM Interop was slow.
In the next phase, we decided to write a custom interop in
MC++ to improve data retrieval rates, etc. Unfortunately,
we had to make some changes in the C# application for the
custom interop to work. Consider the following two
methods (after #import by the C++ compiler):
variant_t getTag(void)
void putTag(const VARIANT& var)
When we use the default COM interop, the C# application
finds VARIANTs as System::Objects. In our C# application,
we can pass any managed object reference in the putTag()
method and later on retrieve it using the getTag()
method. It works fine - RCW does the magic to marshall a
managed object reference straight into the COM layer and
later on it can retrieve it correctly.
I could not replicate this behaviour in my custom
interop :-(. I thought Marshal::GetNativeVariantForObject
() and its counterpart should help me to marshal a managed
object reference. Say, for example:
void ManagedRecord::set_Tag(Object* tagObj /* managed
object from C# app */)
{
try
{
if (m_pRecord != NULL) // unmanaged COM
smart pointer
{
Debug::Assert(tagObj != NULL);
IntPtr intPtr;
Marshal::GetNativeVariantForObject
(tagObj, intPtr);
VARIANT* varTag =
static_cast<VARIANT*>(static_cast<void*>(intPtr));
Debug::Assert(varTag != NULL);
m_pRecord->putTag(*varTag);