親牛の開発日記

ぼけ防止するため、開発メモを残そう

C#から文字列の配列をC/C++ DLLへの渡し方

■ネイティブ関数の引数が「char**」の場合

C関数

void init(int argc, char** argv);

C#

[DllImport("XXXXX.dll")]
public static extern int init(int argc, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex =1)]string argv);

これは無難だろう

 

■ネイティブ関数の引数が構造体であって、その中に「char**」があった場合

C構造体

struct ARGS

{

 int argc;

 char** argv;

};

void init(struct ARGS * pArgs);

 

C#

public struct ARGS
{

int Argc;
IntPtr Argv;

public ARGS(string argv)
{
  Argc = argv.Length;
  Encoding encoding = Encoding.GetEncoding(932);
  List<string> list = new List<string>(argv);
  Argv = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr)) * list.Count);

  for (int index = 0; index < list.Count; index++)
   {
      int len = encoding.GetByteCount(list[index]) + 1;
      IntPtr point = Marshal.AllocCoTaskMem(len);
      Marshal.Copy(encoding.GetBytes(list[index]), 0, point, len - 1);

      Marshal.WriteByte(point, len - 1, 0);

      Marshal.WriteIntPtr(Argv, index * Marshal.SizeOf(typeof(IntPtr)), point);
   }
}

}

[DllImport("XXXXXX.dll")]
public static extern int Init(ref ARGS args);