如何使用C#获取char **?

我需要以下列forms将参数传递给不安全的DllImported函数:

[DllImport("third_party.dll")] private static extern unsafe int start(int argc, char** argv); 

我假设它是一个字符串数组。 但是,当我尝试执行以下操作时,我得到’无法从字符串[]转换为char **’错误。 我如何让这个工作? 谢谢。

 string[] argv = new string[] { }; start(0, argv); 

编辑1:问题被标记为重复,但看着可能重复的问题,我仍然没有看到如何使这个工作。

编辑2:进一步确定问题和所需参数。 它看起来像您的标准argc / argv参数(参数计数,然后是参数值)。 与启动ac程序的方式相同: int main(int argc, char** argv); 对于这个特殊问题,我根本不想传递任何参数(因此count为0)。

编辑3:我从第三方库供应商那里获得了更多信息。 这里是:

  • 第一个参数是参数计数
  • 第二个参数是一个以空字符结尾的字符串数组
  • 字符串是ANSI编码的

编辑4 :使用工作解决方案进行最终编辑(至少在我的情况下)。 我会把它作为答案,但不能,因为这个问题被标记为重复。 这是一个帮助我最多的问题的链接 。 最后,dll函数需要一个指向ANSI字符串缓冲区的指针数组。 所以我的最终方法(基于相关问题)如下。 在内存中创建一个数组来保存指针,然后将每个字符串分配到内存中的其他位置,并在第一个指针数组中写入指向这些字符串的指针。 此代码适用于生产:

 [DllImport("third_party.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private static extern int start(Int32 args, IntPtr argv); public bool start(params string[] arguments) { int result; if (arguments == null || arguments.Length == 0) { result = dll_system_startup(0, IntPtr.Zero); } else { List allocatedMemory = new List(); int sizeOfIntPtr = Marshal.SizeOf(typeof(IntPtr)); IntPtr pointersToArguments = Marshal.AllocHGlobal(sizeOfIntPtr * arguments.Length); for (int i = 0; i < arguments.Length; ++i) { IntPtr pointerToArgument = Marshal.StringToHGlobalAnsi(arguments[i]); allocatedMemory.Add(pointerToArgument); Marshal.WriteIntPtr(pointersToArguments, i * sizeOfIntPtr, pointerToArgument); } result = start(arguments.Length, pointersToArguments); Marshal.FreeHGlobal(pointersToArguments); foreach (IntPtr pointer in allocatedMemory) { Marshal.FreeHGlobal(pointer); } } return result == 0; } 

我想你可能需要使用Marshal。

 var a = (char*)Marshal.StringToCoTaskMemAuto("myString"); char** = &a; 

这只是一个猜测,因为我没有一个需要char **的库,所以我无法尝试它。

相当于C的char**是C#中的完全固定byte[][] (并且完全固定我的意思是外部数组AND所有内部数组)。 如果要传递C#字符串,则必须将它们转换为字节数组,例如使用Encoding.ASCII.GetBytes

你能将DllImport声明参数类型更改为StringBuilder[]吗? 然后你可以调用这个函数:

 StringBuilder[] args = new StringBuilder[] { }; start(args);