Problem with C++ string marshalling in .NET 2.0

G

Guest

I'm working on a project where we're building a .NET wrapper to IBM's MQ
Workflow C++ API.

My original intention was to wrap the Workflow API with a managed C++
assembly that in turn could be consumed by .NET clients. I've developed a
proof of concept app in .NET 1.1 that validated this.

However, the final deliverables need to be in .NET 2.0 so I migrated the 1.1
code to 2.0. After the migration effort, I tried running the app and
immediately received an AccessViolationException - "Attempted to read or
write protected memory. This is often an indication that other memory has
been corrupted".

The code that worked fine in 1.1 doesn't want to play in 2.0 - (snippet below)

//Note: username and password are managed Strings
const char * uUsername = (const
char*)(Marshal::StringToHGlobalAnsi(username)).ToPointer();

const char * uPassword = (const
char*)(Marshal::StringToHGlobalAnsi(password)).ToPointer();

rc = _service->Logon(uUsername, uPassword, FmcjService::Default );

Marshal::FreeHGlobal(System::IntPtr((void*)uUsername));

Marshal::FreeHGlobal(System::IntPtr((void*)uPassword));

The exception is thrown on when the logon is attempted. The assembly is
being compiled using the /clr switch.

Here's the compiler command-line:

/Od /I "C:\Program Files\IBM WebSphere MQ Workflow\API" /AI
"C:\Source\TPoC\Debug" /D "WIN32" /D "_DEBUG" /D "_WINDLL" /D "_MBCS" /FD
/EHa /MDd /GS /Yu"stdafx.h" /Fp"Debug/WFWrapper.pch" /Fo"Debug/"
/Fd"Debug/vc80.pdb" /W3 /nologo /c /Zi /clr /TP /FU
"c:\WINDOWS\Microsoft.NET\Framework\v2.0.40607\mscorlib.dll" /FU
"c:\WINDOWS\Microsoft.NET\Framework\v2.0.40607\System.dll" /FU
"c:\WINDOWS\Microsoft.NET\Framework\v2.0.40607\System.Data.dll" /FU
"c:\WINDOWS\Microsoft.NET\Framework\v2.0.40607\System.Drawing.dll" /FU
"c:\WINDOWS\Microsoft.NET\Framework\v2.0.40607\System.Windows.Forms.dll" /FU
"c:\WINDOWS\Microsoft.NET\Framework\v2.0.40607\System.XML.dll"

.....and the linker command-line

/OUT:"C:\Source\TPoC\Debug\WFWrapper.dll" /INCREMENTAL /NOLOGO /DLL
/MANIFEST
/MANIFESTFILE:"c:\Source\TPoC\debug\WFWrapper.dll.intermediate.manifest"
/INCLUDE:"__DllMainCRTStartup@12" /DEBUG /ASSEMBLYDEBUG
/PDB:"C:\Source\TPoC\Debug/WFWrapper.pdb" /FIXED:No mscoree.lib "C:\Program
Files\IBM WebSphere MQ Workflow\API\*.lib" msvcrtd.lib kernel32.lib
user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib
ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "..\..\Program
Files\Microsoft Visual Studio 8\SDK\v2.0\Lib\mscoree.lib" libsmanifest.res

Has anyone else experienced similar problems in .NET 2.0? Any help in
solving this will be greatly appreciated.

Cheers,

Travis
 
W

William DePalo [MVP VC++]

Travis said:
I'm working on a project where we're building a .NET wrapper to IBM's MQ
Workflow C++ API.
...
The code that worked fine in 1.1 doesn't want to play in 2.0 - (snippet
below)

//Note: username and password are managed Strings
const char * uUsername = (const
char*)(Marshal::StringToHGlobalAnsi(username)).ToPointer();

const char * uPassword = (const
char*)(Marshal::StringToHGlobalAnsi(password)).ToPointer();

rc = _service->Logon(uUsername, uPassword, FmcjService::Default );

I should tell you that I haven't done any .Net 2.0 development so this is a
bit of guesswork. When I looked up the string marshaller in the
documentation I found this about the return value:

<quote>
The address, in unmanaged memory, to where s was copied, or 0 if a null
reference (Nothing in Visual Basic) string was supplied.
</quote>

You may want to remove the calls to ToPointer() .

If that doesn't work, please reply here so that someone else may offer
better advice.

Regards,
Will
 
K

Kapil Khosla [MSFT]

--
This posting is provided "AS IS" with no warranties, and confers no
rights."Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm"

William DePalo said:
I should tell you that I haven't done any .Net 2.0 development so this is
a bit of guesswork. When I looked up the string marshaller in the
documentation I found this about the return value:

<quote>
The address, in unmanaged memory, to where s was copied, or 0 if a null
reference (Nothing in Visual Basic) string was supplied.
</quote>

You may want to remove the calls to ToPointer() .


I dont see anything wrong is using ToPointer() to convert a managed string
to a native string. The issue seems to be in rc = _service->Logon(uUsername,
uPassword, FmcjService::Default );
Could you share out more information on the type rc and _service, without
that it is very hard to understand what is going on.
Thanks.
Kapil
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top