johnsto <an****@anywhere.com> wrote in
news:cd**********@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*.
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.
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/