It is a mistake to use TCHAR
and related types here. The use case of TCHAR
is for code that needs to compile for both Windows 9x which has no Unicode support, and Windows NT which does. Those days are long gone and TCHAR
is obscuring the problem. What's more, the underlying code uses char*
so it makes little sense to pretend that your wrapper code can do anything else. So switch to char
.
On top of that you are casting away const. I guess because the function you call accepts a modifiable buffer for a parameter that it does not modify. Best solution is to fix the original library code that erroneously accepts char*
and make it accept const char*
. If you cannot do that then you'll need to cast away the const. But do that the C++ way with const_cast<>
.
So, I'd have the C++ code like this:
BSTR GroupInit(const char* szIniFile, bool bDiagErr, bool bProcErr) {
CString strResult = "";
char* sz;
::SetVars(bDiagErr, bProcErr);
if (sz = ::GroupInit(const_cast<char*>(szIniFile), 1))
strResult = sz;
return strResult.AllocSysString();
}
And the C# code should be:
[DllImport("GrouperServer.dll", CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.BStr)]
public static extern string GroupInit(
string strCmdFile,
bool bAllowBadDiagCodes,
bool bAllowBadProcCodes
);
Now, one wonders what happens to sz
. Who is expected to deallocate that? Does it even need to be deallocated? Only you can answer those questions.