将指针从C#传递到C+的结构数组指针+; 我想把指针指向一个结构数组的指针,从C到C++。通过以下代码,我只得到C++中的第一个元素,数组的第二个和第三个元素就不会被传递。为什么?另外,尝试使用StructureToPtr,但没有帮助。我做错了什么

将指针从C#传递到C+的结构数组指针+; 我想把指针指向一个结构数组的指针,从C到C++。通过以下代码,我只得到C++中的第一个元素,数组的第二个和第三个元素就不会被传递。为什么?另外,尝试使用StructureToPtr,但没有帮助。我做错了什么,c#,c++,pinvoke,marshalling,unmanaged,C#,C++,Pinvoke,Marshalling,Unmanaged,C++代码 struct structure { short ps; }; __declspec(dllexport)short Testmethod(structure** aa) { if (aa!= 0 && aa[0]->ps == 26 && aa[1]->ps == 27) { return 1; } return 0;

C++代码

 struct structure 
{
   short ps;

};
   __declspec(dllexport)short Testmethod(structure** aa)
    {
     if (aa!= 0 && aa[0]->ps == 26 && aa[1]->ps == 27)
     {          
        return 1;
      }    
      return  0;
    }
[DllImport("Wrapper.dll", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern short Testmethod(ref IntPtr a);

     [StructLayout(LayoutKind.Sequential)]           
     public struct SampleStructure
    {
       public short ps;

    };

 SampleStructure[] data= new SampleStructure[3] { new SampleStructure { ps = 26 }, new SampleStructure { ps = 27 }, new SampleStructure { ps = 28 } };
                        GCHandle gch = GCHandle.Alloc(data, GCHandleType.Pinned);
                        IntPtr ptr = gch.AddrOfPinnedObject();
                        ret = Testmethod(ref ptr);
__declspec(dllexport)short Testmethod(structure* aa)
            fixed (SampleStructure* pArray = dataInformation)
            {
                ret = Testmethod(pArray);
            }
__declspec(dllexport)short Testmethod(structure Getcsharpval[], int size)
 public unsafe static extern short Testmethod([MarshalAs(UnmanagedType.LPArray,SizeParamIndex=3)] SampleStructure[] array);
 SampleStructure[] data= new SampleStructure[3] { new SampleStructure { ps = 26 }, new SampleStructure { ps = 27 }, new SampleStructure { ps = 28 } };
 ret = Testmethod( data);
C#代码

 struct structure 
{
   short ps;

};
   __declspec(dllexport)short Testmethod(structure** aa)
    {
     if (aa!= 0 && aa[0]->ps == 26 && aa[1]->ps == 27)
     {          
        return 1;
      }    
      return  0;
    }
[DllImport("Wrapper.dll", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern short Testmethod(ref IntPtr a);

     [StructLayout(LayoutKind.Sequential)]           
     public struct SampleStructure
    {
       public short ps;

    };

 SampleStructure[] data= new SampleStructure[3] { new SampleStructure { ps = 26 }, new SampleStructure { ps = 27 }, new SampleStructure { ps = 28 } };
                        GCHandle gch = GCHandle.Alloc(data, GCHandleType.Pinned);
                        IntPtr ptr = gch.AddrOfPinnedObject();
                        ret = Testmethod(ref ptr);
__declspec(dllexport)short Testmethod(structure* aa)
            fixed (SampleStructure* pArray = dataInformation)
            {
                ret = Testmethod(pArray);
            }
__declspec(dllexport)short Testmethod(structure Getcsharpval[], int size)
 public unsafe static extern short Testmethod([MarshalAs(UnmanagedType.LPArray,SizeParamIndex=3)] SampleStructure[] array);
 SampleStructure[] data= new SampleStructure[3] { new SampleStructure { ps = 26 }, new SampleStructure { ps = 27 }, new SampleStructure { ps = 28 } };
 ret = Testmethod( data);

我不能更改C++代码,我不能访问它。如果将C++代码作为以下方法之一,它就可以工作了。怎样才能在不改变C++代码的情况下实现呢? 更新:

<强>方法1:如果我改变C++代码。但是我不能改变C++代码。这不是我的密码

C++代码

 struct structure 
{
   short ps;

};
   __declspec(dllexport)short Testmethod(structure** aa)
    {
     if (aa!= 0 && aa[0]->ps == 26 && aa[1]->ps == 27)
     {          
        return 1;
      }    
      return  0;
    }
[DllImport("Wrapper.dll", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern short Testmethod(ref IntPtr a);

     [StructLayout(LayoutKind.Sequential)]           
     public struct SampleStructure
    {
       public short ps;

    };

 SampleStructure[] data= new SampleStructure[3] { new SampleStructure { ps = 26 }, new SampleStructure { ps = 27 }, new SampleStructure { ps = 28 } };
                        GCHandle gch = GCHandle.Alloc(data, GCHandleType.Pinned);
                        IntPtr ptr = gch.AddrOfPinnedObject();
                        ret = Testmethod(ref ptr);
__declspec(dllexport)short Testmethod(structure* aa)
            fixed (SampleStructure* pArray = dataInformation)
            {
                ret = Testmethod(pArray);
            }
__declspec(dllexport)short Testmethod(structure Getcsharpval[], int size)
 public unsafe static extern short Testmethod([MarshalAs(UnmanagedType.LPArray,SizeParamIndex=3)] SampleStructure[] array);
 SampleStructure[] data= new SampleStructure[3] { new SampleStructure { ps = 26 }, new SampleStructure { ps = 27 }, new SampleStructure { ps = 28 } };
 ret = Testmethod( data);
C#代码

 struct structure 
{
   short ps;

};
   __declspec(dllexport)short Testmethod(structure** aa)
    {
     if (aa!= 0 && aa[0]->ps == 26 && aa[1]->ps == 27)
     {          
        return 1;
      }    
      return  0;
    }
[DllImport("Wrapper.dll", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern short Testmethod(ref IntPtr a);

     [StructLayout(LayoutKind.Sequential)]           
     public struct SampleStructure
    {
       public short ps;

    };

 SampleStructure[] data= new SampleStructure[3] { new SampleStructure { ps = 26 }, new SampleStructure { ps = 27 }, new SampleStructure { ps = 28 } };
                        GCHandle gch = GCHandle.Alloc(data, GCHandleType.Pinned);
                        IntPtr ptr = gch.AddrOfPinnedObject();
                        ret = Testmethod(ref ptr);
__declspec(dllexport)short Testmethod(structure* aa)
            fixed (SampleStructure* pArray = dataInformation)
            {
                ret = Testmethod(pArray);
            }
__declspec(dllexport)short Testmethod(structure Getcsharpval[], int size)
 public unsafe static extern short Testmethod([MarshalAs(UnmanagedType.LPArray,SizeParamIndex=3)] SampleStructure[] array);
 SampleStructure[] data= new SampleStructure[3] { new SampleStructure { ps = 26 }, new SampleStructure { ps = 27 }, new SampleStructure { ps = 28 } };
 ret = Testmethod( data);

<强>方法2:如果我改变C++代码。但是我不能改变C++代码。这不是我的密码

C++代码

 struct structure 
{
   short ps;

};
   __declspec(dllexport)short Testmethod(structure** aa)
    {
     if (aa!= 0 && aa[0]->ps == 26 && aa[1]->ps == 27)
     {          
        return 1;
      }    
      return  0;
    }
[DllImport("Wrapper.dll", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern short Testmethod(ref IntPtr a);

     [StructLayout(LayoutKind.Sequential)]           
     public struct SampleStructure
    {
       public short ps;

    };

 SampleStructure[] data= new SampleStructure[3] { new SampleStructure { ps = 26 }, new SampleStructure { ps = 27 }, new SampleStructure { ps = 28 } };
                        GCHandle gch = GCHandle.Alloc(data, GCHandleType.Pinned);
                        IntPtr ptr = gch.AddrOfPinnedObject();
                        ret = Testmethod(ref ptr);
__declspec(dllexport)short Testmethod(structure* aa)
            fixed (SampleStructure* pArray = dataInformation)
            {
                ret = Testmethod(pArray);
            }
__declspec(dllexport)short Testmethod(structure Getcsharpval[], int size)
 public unsafe static extern short Testmethod([MarshalAs(UnmanagedType.LPArray,SizeParamIndex=3)] SampleStructure[] array);
 SampleStructure[] data= new SampleStructure[3] { new SampleStructure { ps = 26 }, new SampleStructure { ps = 27 }, new SampleStructure { ps = 28 } };
 ret = Testmethod( data);
c#代码

 struct structure 
{
   short ps;

};
   __declspec(dllexport)short Testmethod(structure** aa)
    {
     if (aa!= 0 && aa[0]->ps == 26 && aa[1]->ps == 27)
     {          
        return 1;
      }    
      return  0;
    }
[DllImport("Wrapper.dll", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern short Testmethod(ref IntPtr a);

     [StructLayout(LayoutKind.Sequential)]           
     public struct SampleStructure
    {
       public short ps;

    };

 SampleStructure[] data= new SampleStructure[3] { new SampleStructure { ps = 26 }, new SampleStructure { ps = 27 }, new SampleStructure { ps = 28 } };
                        GCHandle gch = GCHandle.Alloc(data, GCHandleType.Pinned);
                        IntPtr ptr = gch.AddrOfPinnedObject();
                        ret = Testmethod(ref ptr);
__declspec(dllexport)short Testmethod(structure* aa)
            fixed (SampleStructure* pArray = dataInformation)
            {
                ret = Testmethod(pArray);
            }
__declspec(dllexport)short Testmethod(structure Getcsharpval[], int size)
 public unsafe static extern short Testmethod([MarshalAs(UnmanagedType.LPArray,SizeParamIndex=3)] SampleStructure[] array);
 SampleStructure[] data= new SampleStructure[3] { new SampleStructure { ps = 26 }, new SampleStructure { ps = 27 }, new SampleStructure { ps = 28 } };
 ret = Testmethod( data);

我认为你的c函数有错误的原型。 尝试:


在c#示例中,您有一个struct数组。数组是引用类型,您需要固定内存。数组是struct内存中的值类型序列(不需要pin)。因此,在数组中没有指针,而是直接使用结构。

我认为您的c函数有错误的proto。 尝试:


在c#示例中,您有一个struct数组。数组是引用类型,您需要固定内存。数组是struct内存中的值类型序列(不需要pin)。因此,在数组中,你没有指针,但直接指向Stutt.< /P> < P>你需要将<代码> ItpTr[] /Cuff>传递给C++代码。p>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
static extern short Testmethod(IntPtr[] aa)

分配一个
IntPtr[]
数组并填充它。通过固定每个结构和使用固定对象的地址来执行此操作。或者使用
Marshal.StructureToPtr
执行此操作。如果使用后者,则必须在调用后释放非托管内存

< p>您需要将 ItpTr[] /Cuff>传递给C++代码。
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
static extern short Testmethod(IntPtr[] aa)

分配一个
IntPtr[]
数组并填充它。通过固定每个结构和使用固定对象的地址来执行此操作。或者使用
Marshal.StructureToPtr
执行此操作。如果使用后者,则必须在调用后释放非托管内存

好的,我通过使用以下代码创建指向结构指针的指针来解决

    [DllImport("Wrapper.dll", CallingConvention = CallingConvention.StdCall)]
    public unsafe static extern short Testmethod (SampleStructure** passstructurepointer);

     unsafe
            {
                fixed(SampleStructure** p2p = new SampleStructure*[3])
                {
                    for (short i = 0; i < 3; i++)
                    {
                        var a = stackalloc SampleStructure[1];
                        a->ps = i;
                        p2p[i] = a;
                    }
                    var s= Testmethod(p2p);
                }
            }
[DllImport(“Wrapper.dll”,CallingConvention=CallingConvention.StdCall)]
公共不安全静态外部短测试方法(SampleStructure**passstructurepointer);
不安全的
{
固定(SampleStructure**p2p=新的SampleStructure*[3])
{
对于(短i=0;i<3;i++)
{
var a=stackalloc样本结构[1];
a->ps=i;
p2p[i]=a;
}
var s=测试方法(p2p);
}
}

好的,我通过使用以下代码创建指向结构指针的指针来解决问题

    [DllImport("Wrapper.dll", CallingConvention = CallingConvention.StdCall)]
    public unsafe static extern short Testmethod (SampleStructure** passstructurepointer);

     unsafe
            {
                fixed(SampleStructure** p2p = new SampleStructure*[3])
                {
                    for (short i = 0; i < 3; i++)
                    {
                        var a = stackalloc SampleStructure[1];
                        a->ps = i;
                        p2p[i] = a;
                    }
                    var s= Testmethod(p2p);
                }
            }
[DllImport(“Wrapper.dll”,CallingConvention=CallingConvention.StdCall)]
公共不安全静态外部短测试方法(SampleStructure**passstructurepointer);
不安全的
{
固定(SampleStructure**p2p=新的SampleStructure*[3])
{
对于(短i=0;i<3;i++)
{
var a=stackalloc样本结构[1];
a->ps=i;
p2p[i]=a;
}
var s=测试方法(p2p);
}
}

我对PoNoCK的编写方法没有太多的经验,但是,你尝试过把C++方法的签名改成<代码>简短测试方法(结构*AA)< /C>?编辑:同样,因为你传递了一个指针,你也应该传递数据的长度。你可以在你的项目中使用C++/CLI吗?我对编写适合pPiNKE的方法没有太多的经验,但是,你试过把C++方法的签名改成<代码>简短测试方法(结构*AA)< /C++ >吗?编辑:同样,因为你传递了一个指针,你也应该传递数据的长度。你可以在项目中使用C++吗?我不能改变C++代码,我没有访问它的权限。如果改变C++代码,它就可以工作。怎样才能在不改变C++代码的情况下实现呢?请参考最新的问题,我不能更改C++代码,我没有权限访问它。如果改变C++代码,它就可以工作。怎样才能在不改变C++代码的情况下实现呢?请参阅更新的问题不需要不安全或stackalloc不需要不安全或stackalloc