This was marked as a duplicate of Pass writeable StringBuilder array to C++ from C# but that does not at all address the issue of the use of StringBuilder[] and only comments on the incorrect use of wcsncpy and MarshalAs. I am not even using wcsncpy or MarshalAs anywhere in my question.
So, I'm trying to use one of my C++ functions in C# like this:
[DllImport("CPPDLLImport", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
static extern void StringBuilderArrayTest(StringBuilder[] text, int[] textLengths, int numberOfTextItems);
Now, normally this would work fine of course, but I'm don't think I'm getting the correct data in C++ from text.
So, in order to test this I set up a P/Invoke project.
I am calling the method in C# using this:
var stringBuilderArray = new StringBuilder[]
{
new StringBuilder("abc"),
new StringBuilder("def"),
new StringBuilder("ghi")
};
var stringBuilderLengths = new int[3] { 3, 3, 3 };
StringBuilderArrayTest(stringBuilderArray, stringBuilderLengths, 3);
And this is my method in C++ - to test it I'm just printing it to the screen, and to make sure it definitely wasn't printf, I am literally printing it character-by-character just to be sure:
EXPORT void StringBuilderArrayTest(wchar_t** text, int* textLengths, int numberOfTextItems) {
for (int i = 0; i < numberOfTextItems; i++)
for (int j = 0; j < textLengths[i]; j++)
printf("%c", text[i][j]);
}
And, well, the parameter text is definitely not right. It's just giving me "ÇPÿ" three times - definitely not the string "abc", "def" or "ghi".
Is it just not marshaling the StringBuilder array correctly? If so, how can I get this array of strings across?
UPDATE:
OK, I have decided to use a string[] for sending data to my C++ code, however, I now need to do the reverse - sending data from C++ into C#. So, what alternatives are there to using an array of StringBuilder?
wchar_t**Double stars in C++ are hard-enough to deal with in C++ code itself. It's not surprising things are not working for a language that isn't C++. Maybe there is a way to do this, but if it were me, I would just send a single string, maybeabc;def;ghi, and deal with that by parsing out the;.StringBuilderis less costly than concatenation when creating a string from other strings.But I don't see that happening in the code. If you're instantiating a string from a character array, you can dovar myString = new string(someCharArray);StringBuilderunless you plan to modify the string on the C++ side and use the modified value back in C#. And there is no marshalling forStringBuilder[], so you can only do one at a time.