Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / July 2005

Tip: Looking for answers? Try searching our database.

HOWTO: passing an [in,out] char* from Managed C++ to Unmanaged C.

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Sam Carleton - 11 Jul 2005 22:08 GMT
I am writing Managed C++ code to call in to an Unmanaged C API.
The reason for using Managed C++ over C# is that the Unmanaged C
module is loaded via LoadLibrary().  DllImport cannot be used;
functions pointers and GetProcAddress() is being used.

The API function definition looks like this:

int GetString( [out] char* pszOutStr, [in,out] int *nStrLen)

It looks like the prototyping of the function pointer is straight
forward:

typedef int (*FPGetString)( char* pszOutStr, int *nStrLen);

The question is how do I get a char* with a given length to pass
into this function.  Mind you this IS an Ansi call, not Unicode!

Sam
Sam Carleton - 12 Jul 2005 00:16 GMT
> I am writing Managed C++ code to call in to an Unmanaged C API.
> The reason for using Managed C++ over C# is that the Unmanaged C
[quoted text clipped - 14 lines]
>
> Sam

Ok, looks like an [out] is simple:

int nStrLen = x;
IntPtr ptrOut = Marshal::AllocHGlobal( nStrLen * sizeof(char));
GetString( (char*) ptrOut.ToPointer(), &nStrLen);
Marshal::FreeCoTaskMem(ptrOut);

This is working fine for me.  The problem I am having now is the
[in, out].  There is another method that one of the three
parameters which is an in/out is the username.  The size of the
username buffer must the full length possible for a username in
this app.  The API call might prompt the user and the user might
change the username, so the new username is returned in the same
string that was passed in.  Crasy, but that is what I have to work
with.  Here is my best guess, which is blowing up when I call Free
the memory:

StringBuilder * outUser = new StringBuilder( user, USER_LEN+1);
IntPtr ptrUsername = Marshal::StringToHGlobalAnsi(outUser->ToString());
// I don't know if the pin is really needed, but it compiles
char __pin* pszUsername = (char*) ptrUsername.ToPointer();

login( pszUsername, ...);

String * strUser = Marshal::PtrToStringAnsi(ptrUsername);

Marshal::FreeCoTaskMem(ptrUsername);

To tell the truth, the username is freed without any problems, it
is the parameter after it, which is also a [in, out] char* that
blows chunks (unhandled exception) when calling
Marshal::FreeCoTaskMem().

Any thoughts?

Sam
Willy Denoyette [MVP] - 12 Jul 2005 12:34 GMT
AllocHGlobal should be paired with FreeHGlobal not FreeCoTaskMem!

Willy.

>> I am writing Managed C++ code to call in to an Unmanaged C API.
>> The reason for using Managed C++ over C# is that the Unmanaged C
[quoted text clipped - 51 lines]
>
> Sam

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.