Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C# string to C++ dll char*

1 view
Skip to first unread message

johnsto

unread,
Jul 18, 2004, 7:08:06 AM7/18/04
to
I'm really stuck - can someone help me!

I've got a basic setup consisting of two things:
1. A C# web service
2. An unmanaged C++ DLL

The WS is intended to call some functions in the DLL. The DLL has some
legacy code which requires char* in its method parameters.

I also have a new file in the DLL which is basically an intermediary -
the WS can call the exported functions from this file, which then call
the legacy code. The problem is converting from the native C# strings in
the WS to the char*'s in the C++ code.

So, the WS calls method(string) in the DLL, and the DLL then needs to
call method(char*) in its C++ code, where string==char*.

At the moment I have the DLL exporting method(String*)'s, but of course
in C# I can't get the address of a string to pass to the method. If I
change the DLL methods to method(String) (ie. no pointer), the compiler
complains that they HAVE to be pointers. I can't use method(char*)
either because then I'm back to the original problem of C# not wanting
to call a method with a char* in it.

Help!

Shakir Hussain

unread,
Jul 18, 2004, 3:20:30 PM7/18/04
to
For char*, you have to do this

byte [] str = new byte [255];

Pass str to the function

--
Shak
(Houston)


"johnsto" <any...@anywhere.com> wrote in message
news:cddlmm$fac$1...@titan.btinternet.com...

Chris R. Timmons

unread,
Jul 18, 2004, 3:51:40 PM7/18/04
to
johnsto <any...@anywhere.com> wrote in
news:cddlmm$fac$1...@titan.btinternet.com:

You can use the either the System.String or System.Text.StringBuilder
class. The underlying P/Invoke marshalling code in the .Net
framework will do all of the messy character pointer conversions for
you. If the string parameter is used as an output or input/output
buffer, then use StringBuilder. Otherwise if the string parameter is
input-only you can use the String class.

For example, the Win32 API function GetPrivateProfileString has both
input-only string parameters, and a string output parameter. Here's
how it can be accessed in C# using the String and StringBuilder
classes as parameter types:

/* Original C Method Signature:

DWORD GetPrivateProfileString(
LPCTSTR lpAppName,
LPCTSTR lpKeyName,
LPCTSTR lpDefault,
LPTSTR lpReturnedString,
DWORD nSize,
LPCTSTR lpFileName
);

*/

[DllImport("kernel32", EntryPoint="GetPrivateProfileString",
SetLastError = false, CharSet = CharSet.Auto)]
private static extern long GetPrivateProfileString(
string lpApplicationName, // in
string lpKeyName, // in
string lpDefault, // in
StringBuilder lpReturnedString, // out
int nSize, // in
string lpFileName); // in


public string GetIniValue(
string iniFileName,
string sectionName,
string keyName,
string defaultValue)
{
const int maxlen = 255;

StringBuilder sBuffer = new StringBuilder(maxlen);

// The P/Invoke marshaller takes care of converting the
// String and StringBuilder parameters to/from
// character pointers.

GetPrivateProfileString(sectionName, keyName, defaultValue,
sBuffer, maxlen, iniFileName);

return sBuffer.ToString();
}

--
Hope this helps.

Chris.
-------------
C.R. Timmons Consulting, Inc.
http://www.crtimmonsinc.com/

johnsto

unread,
Jul 18, 2004, 5:09:07 PM7/18/04
to
Chris R. Timmons wrote:
> You can use the either the System.String or System.Text.StringBuilder
> class. The underlying P/Invoke marshalling code in the .Net
> framework will do all of the messy character pointer conversions for
> you. If the string parameter is used as an output or input/output
> buffer, then use StringBuilder. Otherwise if the string parameter is
> input-only you can use the String class.

It is input-only... so you're saying if I pass it a System::String, it
will convert to a char* automatically?

I mean, the very basic version of the problem is converting the
System::String to char*, and working out where to do the conversion. The
C++ requires char*, the C# WS needs String (it makes life complicated
and complains about char*), and the DLL intermediary is there really
just to forward method calls and handle any parameter conversion.

Part of the problem is actually convincing the C# bit to let me use
String* as a pointer - which I can then pass to the DLL... That's the
last hurdle that got me before I gave up for the weekend...

Argh!!!

BMermuys

unread,
Jul 18, 2004, 5:44:29 PM7/18/04
to
Hi,

"johnsto" <any...@anywhere.com> wrote in message
news:cddlmm$fac$1...@titan.btinternet.com...

> I'm really stuck - can someone help me!
>
> I've got a basic setup consisting of two things:
> 1. A C# web service
> 2. An unmanaged C++ DLL
>
> The WS is intended to call some functions in the DLL. The DLL has some
> legacy code which requires char* in its method parameters.
>
> I also have a new file in the DLL which is basically an intermediary -
> the WS can call the exported functions from this file, which then call
> the legacy code. The problem is converting from the native C# strings in
> the WS to the char*'s in the C++ code.
>
> So, the WS calls method(string) in the DLL, and the DLL then needs to
> call method(char*) in its C++ code, where string==char*.

The dll (intermediary) that WS suppose to call, is it a managed c dll or a
plain old c dll ? Because that's still not very clear here.


HTH,
greetings

Chris R. Timmons

unread,
Jul 18, 2004, 7:37:46 PM7/18/04
to
johnsto <any...@anywhere.com> wrote in
news:cdeotj$1rq$1...@titan.btinternet.com:

> Chris R. Timmons wrote:
>> You can use the either the System.String or
>> System.Text.StringBuilder class. The underlying P/Invoke
>> marshalling code in the .Net framework will do all of the messy
>> character pointer conversions for you. If the string parameter
>> is used as an output or input/output buffer, then use
>> StringBuilder. Otherwise if the string parameter is input-only
>> you can use the String class.
>
> It is input-only... so you're saying if I pass it a
> System::String, it will convert to a char* automatically?

Yes.

> I mean, the very basic version of the problem is converting the
> System::String to char*, and working out where to do the
> conversion. The C++ requires char*, the C# WS needs String (it
> makes life complicated and complains about char*), and the DLL
> intermediary is there really just to forward method calls and
> handle any parameter conversion.
>
> Part of the problem is actually convincing the C# bit to let me
> use String* as a pointer - which I can then pass to the DLL...
> That's the last hurdle that got me before I gave up for the
> weekend...

Are you trying to use a "string *" in the C# code? Just try a plain
old System.String. If that doesn't work, try
System.Text.StringBuilder. I don't think there's any need to use
pointers (*) in the C# code.

To see why, look at the example code I posted. The C "LPSTR"
parameter type means "Long Pointer to STRing", which is a typedef for
"char *". And LPCSTR means "Long Pointer to a Const STRing", which
is a typedef for "const char *" (see WTypes.h for the
actual typedefs). The P/Invoker marshaller correctly translates from
System.String to LPCSTR, and from System.Text.StringBuilder to LPSTR.

johnsto

unread,
Jul 19, 2004, 3:16:42 AM7/19/04
to
BMermuys wrote:
> Hi,
> "johnsto" <any...@anywhere.com> wrote in message
>>I've got a basic setup consisting of two things:
>>1. A C# web service
>>2. An unmanaged C++ DLL
> The dll (intermediary) that WS suppose to call, is it a managed c dll or a
> plain old c dll ? Because that's still not very clear here.

It's unmanaged - I think it was throwing up errors as a managed DLL (due
to the legacy stuff). I guess that makes it 'plain old c' although I'm
building it with VS2003.

BMermuys

unread,
Jul 19, 2004, 7:32:13 AM7/19/04
to

"johnsto" <any...@anywhere.com> wrote in message
news:cdfsgq$lre$1...@sparta.btinternet.com...

ok, no problem, then you have to follow Chris' replies.

Greetings


johnsto

unread,
Jul 19, 2004, 2:33:10 PM7/19/04
to
Chris R. Timmons wrote:
> To see why, look at the example code I posted. The C "LPSTR"
> parameter type means "Long Pointer to STRing", which is a typedef for
> "char *". And LPCSTR means "Long Pointer to a Const STRing", which
> is a typedef for "const char *" (see WTypes.h for the
> actual typedefs). The P/Invoker marshaller correctly translates from
> System.String to LPCSTR, and from System.Text.StringBuilder to LPSTR.

Damn, .NET is so smart :)

0 new messages