Member Avatar for Member #264455

Hello everyone,
I have a problem in my Borland C++ project.
I need to use my own COM object written in C# (this COM allows me to directly print PDF files) in my another project in C++, but as soon as I call some COM functions which require a string parameter (output file path) my COM throws an exception: Illegal characters in path. So I used for (int i = 0; i < mDocumentFileName.Length; i++) and I found out that at the end of the string there is a \0 character. As far as I know a typical string ends with \0 so the Lenght param should return the number of character before the \0 is reached so if the mDocumentFileName = "out.pdf" it should ends with 'f' not with '\0'. In Borland C++, I use AnsiToOLESTR to convert ansi strings to wchar_t strings.

What's wrong? Or how to solve this?
Thanks.

Dani AI

Generated

Short answer: the string your C# COM receives contains a literal NUL character that was included in the native-side BSTR’s length. BSTRs store a length and a terminating NUL separately; if the native code allocates a BSTR while accidentally including the terminator in the requested length, the managed System.String will contain a trailing '\0' (so Length is one too large) and file APIs often reject that as an illegal path character.

Why it happens and how to verify

  • Small native helpers/macros (older Borland helpers included) sometimes call SysAllocStringLen or otherwise copy length+1 characters, which makes the BSTR length include the terminating NUL. That produces exactly the symptom you saw. ’s suggestion to test with a tiny program is the right first step — reproduce the conversion in isolation and inspect the received string in C# (print the last character code or check for '\0').

Practical fixes

  • Defend in managed code (quick workaround): remove trailing NULs before using the path:

    // C#: remove any trailing NUL characters
    mDocumentFileName = mDocumentFileName.TrimEnd('\0');

    This is safe as a short-term fix but masks the root cause.

  • Fix on the native side (recommended): make a proper BSTR and pass that. Convert ANSI→wide explicitly and use SysAllocString (or SysAllocStringLen with the exact character count, not count+1). Example pattern:

    // native C++ (concept)
    int n = MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, nullptr, 0);
    wchar_t* buf = new wchar_t[n];
    MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, buf, n);
    BSTR b = SysAllocString(buf);   // SysAllocString sets length correctly
    // pass b to COM, then SysFreeString(b) when done
    delete[] buf;

Checklist / troubleshooting

  • Inspect what Borland’s AnsiToOLESTR actually expands to; if it uses SysAllocStringLen check whether it passes wcslen+1.
  • Test with a minimal caller and log character codes at the C# side to prove the trailing NUL.
  • Free BSTRs and avoid leaking memory.
  • Prefer fixing the native allocation; use TrimEnd('\0') only as a defensive fallback.

This ties back to ’s observation that the string contained an extra '\0' — the root cause is almost always how the BSTR was created on the C++ side rather than a bug in .NET string handling.

Recommended Answers

All 2 Replies

Create a small program to test out that function and find out how it works. I don't use that compiler so I can't help you very much. Working with small two or three line programs is a lot easier than trying to work with large programs and DLLs.

Member Avatar for Member #264455

My testing program contains this:

pdf->InitializeDocument(AnsiToOLESTR("out.pdf"));
pdf->SaveDocument();

AnsiToOLESTR generates wide string from ansi string that I use.
My C# COM only copies the string and uses it when I call pdf->SaveDocument(), but at that line: mPdfDocument.Save(mDocumentFileName); an exception is thrown because another \0 character appears at the end of the string caused by the Length which returns "original length + 1". I have to use this:
String tmp = mDocumentFileName.Substring(0, mDocumentFileName.Length - 1);
mPdfDocument.Save(tmp);
instead to make it working.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.