469,331 Members | 5,428 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,331 developers. It's quick & easy.

GetNativeVariantForObject

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);
Nov 16 '05 #1
2 5211
Pratul,
But GetNativeVariantForObject sets intPtr to 0 and the
rest obviously does not work.


GetNativeVariantForObject doesn't change intPtr (not possible since
it's passed by value). It expects intPtr to already point to the
memory where you want the VARIANT to be stored. So try this

VARIANT varTag;
::VariantInit(&varTag);
IntPtr intPtr = (IntPtr)&varTag;
Marshal::GetNativeVariantForObject(tagObj, intPtr);

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.
Nov 16 '05 #2
Mattias

Thank you very much. It works. Your website,
http://www.dotnetinterop.com/ is also very good.

Regards

Pratul
Nov 16 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.