1

Marshalling char array.

The C typedef of the function is:

typedef bool (*get_VariableInfoFunc)(int *, char * *, int *, int *);

It`s usage is like:

pnVariableIdArray = new (nothrow) int[numVars];
pcVariableName = new (nothrow) char*[numVars];
for (int i = 0; i < numVars; i++)
{
    pcVariableName[i] = new char[100];
}
pnUnVariableIdArray = new (nothrow) int[numVars];
pnVariableType = new (nothrow) int[numVars];
res = get_VariableInfo(pnVariableIdArray, pcVariableName, pnUnVariableIdArray, pnVariableType);

My C# Signature is:

[DllImport(AUTODYNResultsApiDll, EntryPoint = "get_VariableInfo", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetVariableInfo(
    int[] pnVariableIdArray,
    IntPtr[] pcVariableName,
    int[] pnUnVariableIdArray,
    int[] pnVariableType);

I use it like:

var stringPointers= new IntPtr[numVars];
for (int i = 0; i < numVars; i++)
{
    by[i] = Marshal.AllocHGlobal(100);
}
GetVariableInfo(pnVariableIdArray, stringPointers, pnUnVariableIdArray, pnVariableType);

and then back to string with:

var strings = new string[numVars];
for (int i = 0; i < numVars; i++)
{
    strings[i] = Marshal.PtrToStringAnsi(by[i]);
}

Is there a nicer way doing this without freeing the Memory of the pointer. Just copy the char array as string array?

1 Answer 1

1

First of all, a few problems with your code as it stands:

  1. The calling convention is cdecl, you need to include CallingConvention = CallingConvention.Cdecl in your attribute.
  2. You set SetLastError = true, but the unmanaged function surely does not call SetLastError. If that is so, remove SetLastError = true.
  3. You call AllocHGlobal but there is no matching call to FreeHGlobal, and so the memory is leaked.
  4. Your assumption that no string will exceed a length of 100 (including null terminator) seems brittle, and at risk of buffer overflow.

As far as the main body of your question goes, the marshaller won't marshal an array of strings for you. Your current approach, subject to the provisos above, is the correct way to tackle the problem.

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

Comments

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.