8

I've already written this piece of code which works fine:
C++ code

extern "C"
{
    const MYLIBRARY_EXPORT char* giefStrPlx(char* addon)
    {
        return addon;
    }
}

C# code

[DllImport("ClassLibrary1")]
private static extern IntPtr giefStrPlx(string x);

void Start()
{

    IntPtr stringPtr = giefStrPlx("Huntsman");
    string huntsman = Marshal.PtrToStringAnsi(echoedStringPtr);
}

After this huntsman contains "Huntsman".


My problem is the step of doing something similar for an array of strings. I wrote the following function

extern "C"
{
    const MYLIBRARY_EXPORT bool fillStrArray(char** lizt, int* length)
    {
        char* one = "one";
        char* two = "two";
        char* three = "three";

        lizt[0] = one;
        lizt[1] = two;
        lizt[2] = three;

        *length = 3;
    }
}

I then tried to write the following piece of code in C#

[DllImport("ClassLibrary1")]
private static extern bool fillStrArray(ref IntPtr array, ref int length);

void Start()
{
    IntPtr charArray = IntPtr.Zero;
    int charArraySize = 0;
    fillStrArray(ref charArray, ref charArraySize);

    IntPtr[] results = new IntPtr[charArraySize];
    Marshal.Copy(charArray, results, 0, charArraySize);

    foreach (IntPtr ptr in results)
    {
        string str = Marshal.PtrToStringAnsi(ptr);
    }
}

Which does not work. So now I'm a bit lost on how to accomplish this.

2
  • Your C code requires you to pass a pointer to memory that it can write the string pointers to. IntPtr.Zero is not writable. You also don't know how much memory you need to allocate. Use IntPtr charArray = Marshal.AllocHGlobal(crossMyFingers) where crossMyFingers is a large number that needs to be at least 3 * IntPtr.Size for this code but should be larger to reduce the odds of heap corruption. You can set the length argument to help it avoid this kind of corruption. Commented Sep 25, 2015 at 16:08
  • Thanks for the pointer. I was still having problems even with the change. I'm trying to use this with Unity and the plugin crashes it, which makes debugging even harder. Instead of passing a pointer to an array I just returned a pointer, not unlike I did in the first example. Commented Sep 30, 2015 at 12:12

1 Answer 1

1

Here are the two helper functions I have from CLR to std::string and from std::string to string CLR

std::string CLROperations::ClrStringToStdString(String^ str)
{
    if (String::IsNullOrEmpty(str))
        return "";

    std::string outStr;
    IntPtr ansiStr = System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str); 
    outStr = (const char*)ansiStr.ToPointer(); 
    System::Runtime::InteropServices::Marshal::FreeHGlobal(ansiStr); 
    return outStr;
}

String ^ CLROperations::StdStringToClr(std::string str)
{
    return gcnew String(str.c_str());
}

for using a List of strings you will need to use List<String^>^ mind the capital String. for a list of std::string use std::vector<std::string>

Sign up to request clarification or add additional context in comments.

2 Comments

I'm sorry but I don't understand how this helps me with the problem I have.
Don't use IntPtr,and char*. Use std::string instead

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.