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

Ete*_*l21 11 c# unsafe marshalling dllimport char

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

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

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

string[] argv = new string[] { };
start(0, argv);
Run Code Online (Sandbox Code Playgroud)

编辑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<IntPtr> allocatedMemory = new List<IntPtr>();

        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;
}
Run Code Online (Sandbox Code Playgroud)

Rom*_*Coo 0

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

StringBuilder[] args = new StringBuilder[] { };
start(args);
Run Code Online (Sandbox Code Playgroud)