通过引用从 c# 将 char** 传递给非托管 C++

Posted

技术标签:

【中文标题】通过引用从 c# 将 char** 传递给非托管 C++【英文标题】:Pass char** by reference from c# to unmanaged C++ 【发布时间】:2015-10-12 18:24:48 【问题描述】:

这是 C# 代码。

namespace CameraTest

    class Program
    
        static void Main(string[] args)
        
            string[] lst = new string[10];
            for (int i = 0; i < 10; i++)
            
                lst[i] = new string(' ', 33);
            
            bool sync = true;
            bool ret = CameraCalls.CAM_EnumCameraEx(sync, lst, 10, 33);

        
    

    public static class CameraCalls
    
        [DllImport("CamDriver64.dll")]
        public static extern bool CAM_EnumCameraEx(bool sync,
                                                   [MarshalAs(UnmanagedType.LPArray)]
                                                   string[] lst, 
                                                   long maxCam, 
                                                   long maxChar);
    

非托管方法是这样的。

BOOL WINAPI CAM_EnumCameraEx(BOOL bSynchronized, char **ppCameraList, long lMaxCamera, long lMaxCharacter);

该方法写入传入的字符串数组。有没有办法从 c# 调用这个方法并使非托管代码能够写入字符串数组?

【问题讨论】:

Marshaling Different Types of Arrays 那个文档有答案,我所要做的就是使用 In, Out 【参考方案1】:

感谢 Remus Rusanu 链接有答案。我所要做的就是用 lst 参数上的 [In, Out] 进行装饰。

namespace CameraTest

    class Program
    
        static void Main(string[] args)
        
            int maxCam = 10,
                 maxChar = 33;

            var lst = (new object[maxCam]).Select(o => new string(' ', maxChar)).ToArray();
            bool sync = true;
            bool ret = CameraCalls.CAM_EnumCameraEx(sync, lst, maxCam, maxChar);

        
    

    public static class CameraCalls
    
        [DllImport("CamDriver64.dll")]
        public static extern bool CAM_EnumCameraEx(bool sync,
                                                   [In, Out]
                                                   string[] lst, 
                                                   long maxCam, 
                                                   long maxChar);
    

【讨论】:

刚刚用StringBuilder[] 测试了我的答案并得到堆栈不平衡错误,所以我认为@HansPassant 是对的。仍然很高兴我创建一个已经传播的任何对象的新数组的方式:) 好吧,直到我添加了 [In, Out] 它不起作用,它要么不设置字符串,要么抛出内存异常。因此,如果 [In, Out] 错误,从外部方法获取数据的正确方法是什么?我应该使用什么来代替 long? 我不愿意花时间帮忙。您已经回答了自己的问题,这表明您已经下定决心。

以上是关于通过引用从 c# 将 char** 传递给非托管 C++的主要内容,如果未能解决你的问题,请参考以下文章

将回调参数从 C# 传递到非托管 C++

将 C# 方法暴露给非托管

将多维数组从托管代码传递到非托管代码

将托管类中包含的非托管指针字段传递给非托管代码

将 C# 字符串传递给 C++,并将 C++ 结果(字符串、char*.. 任何)传递给 C#

创建可以从 c# 和 c++ 中使用的 c# dll