本文介绍了如何使用C#获取char **?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to pass an argument to an unsafe DllImported function in the form of:

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

我假设它是一个字符串数组.但是,当我尝试执行以下操作时,出现无法从string []转换为char **"错误.我如何才能使它正常工作?谢谢.

I'm assuming it's an array of strings. However when I try to do the following, I get 'Cannot convert from string[] to char**' error. How do I go about getting this to work? Thanks.

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

  • 字符串是ANSI编码的
  • 编辑4 :使用有效的解决方案进行最终编辑(至少在我看来是这样).我会以此为答案,但不能这样做,因为此问题被标记为重复.这是一个链接对我帮助最大的问题.最后, dll函数期望一个指向带有ANSI字符串的缓冲区的指针数组.因此,我的最终方法(基于链接的问题)如下.在内存中创建一个数组来保存指针,然后将每个字符串分配到内存中的其他位置,然后将指针写入第一个指针数组中的那些字符串.该代码可用于生产环境:

    EDIT 4: Final edit with a working solution (at least in my case). I would make this the answer, but can't because this question is marked as a duplicate. Here's a link to a question that helped me the most. In the end the dll function expected an array of pointers to buffers with ANSI strings. So my final approach (based off the linked question), was as follows. Create an array in memory to hold the pointers, then allocate each string elsewhere in memory, and write pointers to those strings inside the first pointer array. This code works in production:

    [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;
    }
    

    推荐答案

    我认为您可能需要使用元帅.

    I think you might need to use Marshal.

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

    这只是一个猜测,因为我没有带char **的库,所以我无法尝试.

    This is just a guess because I don't have a library that takes char** so I haven't been able to try it.

    这篇关于如何使用C#获取char **?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    07-28 06:37