471,338 Members | 915 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,338 software developers and data experts.

passing c# object as paramater to managed c++ method

I have a managed C++ method that wraps unmanaged code and creates a
managed object holding data retrieved form an unmanged one. I want
create an instance of this managed class in C#, pass it to this method
and have it set the instance to hold the right data.
From what I've read it seems I should be able to pass C# objects to

managed C++ methods and it should just work; however, when I try it, my
C# instance comes out null. If I step into the C++ method, the
debugger says the parameter is out of scope, but it doesn't throw an
exception when the parameter is referred to in the code -- I assume
this is a debugger problem. But I still don't understand why it
doesn't come out correctly set.

Sorry if this question is unclear. Here's my code, hopefully it will
be more illuminating:

// C# code
public int GetLevel1()
{
// create the managed object in C#
BWCMsgLevel1 msg = null;
// if I instantiate it, then I can set the individual fields
// in the C++ code (see note below)
// BWCMsgLevel1 msg = new BWCMsgLevel1();

// call the managed C++ code, passing the managed object as a
parameter
int result = _DataConnection.GetLevel1(m_Symbol, msg);
return result;
}

// managed C++ code
BOOL Wrapper::GetLevel1(String* sSymbol, BWCMsgLevel1*
pMsgLevel1Managed)
{
// put the String into an LPCTSTR
LPCTSTR lpctSymbol;
const char * c = (const
char*)(System::Runtime::InteropServices::Marshal:: StringToHGlobalAnsi(sSymbol)).ToPointer();
std::string str = c;

System::Runtime::InteropServices::Marshal::FreeHGl obal(System::IntPtr((void*)c));
lpctSymbol = str.c_str();

// create a local instance of the managed object
BWCMsgLevel1* pTest;

// create a local instance of the unmanaged object
CMsgLevel1* pMsgLevel1 = new CMsgLevel1();

// call unmanaged code to fill msgLevel1 with correct data
int nResult = m_pCStockCache->GetLevel1(lpctSymbol, pMsgLevel1, 0, 0);

if(nResult != 0)
{
// if successful getting data out of cache, put data into a
BWCMsgLevel1 object

// create a managed array of bytes
byte arr __gc[] = new byte __gc[pMsgLevel1->GetSize()];

// copy bytes from unmanaged msgLevel1 to managed arr
Marshal::Copy(msgLevel1, arr, 0, pMsgLevel1->GetSize());

// set pTest to an instance of the managed class
// at this point, I can see pTest and check its members and they are
all set correctly
pTest = new BWCMsgLevel1(arr, true);

// set parameter pMsgLevel1Managed equal to pTest
pMsgLevel1Managed = pTest;

// copy fields from unmanaged c++ level1 object to managed .NET
level1 object.
// This code works if pMsgLevel1Managed isn't null, but I would
prefer
// not to have to write code to copy each field because there are
going to be
// many, many more fields.
// The debugger still says pMsgLevel1Managed is out of scope, but I
can
// step through these lines without an error, and when I inspect the
object
// in C# the fields are set correctly.
//pMsgLevel1Managed->m_bDecimal = pMsgLevel1->m_bDecimal;
//pMsgLevel1Managed->m_cAskMC = pMsgLevel1->m_cAskMC;
//pMsgLevel1Managed->m_cBidMC = pMsgLevel1->m_cBidMC;
}

return nResult;
}

BWCMsgLevel1 is defined in a C# library that both this C# project and
the managed C++ project can see.
I'm not a C++ programmer so maybe I'm missing something. If there is a
better place to post this, please let me know. Thanks for your help.

Jul 21 '05 #1
1 3259
The solution was given to me in
microsoft.public.dotnet.languages.csharp. It's to use an additional
level of indirection when passing the parameter, ie, BWCMsgLevel1**.

Jul 21 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Mike Dinnis | last post: by
11 posts views Thread by John Pass | last post: by
17 posts views Thread by =?Utf-8?B?U2hhcm9u?= | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.