Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将带有字符串和数组的结构从托管代码封送到非托管代码_C#_C++_Marshalling_Unmanaged_Managed - Fatal编程技术网

C# 将带有字符串和数组的结构从托管代码封送到非托管代码

C# 将带有字符串和数组的结构从托管代码封送到非托管代码,c#,c++,marshalling,unmanaged,managed,C#,C++,Marshalling,Unmanaged,Managed,我有一个简单的C#数据结构,包含一个字符串、一个int和一个int向量: class MyManagedClass { public string m_Str; int m_Int; int[] m_IntArray; } < C++中的等价物是: struct myUnmanagedStruct { char* m_Str; UINT m_Int; UINT* m_IntArray; } 我有一个非托管函数,用于创建myUnmanagedSt

我有一个简单的C#数据结构,包含一个字符串、一个int和一个int向量:

class MyManagedClass
{
    public string m_Str;
    int m_Int;
    int[] m_IntArray;
}
< C++中的等价物是:

struct myUnmanagedStruct
{
    char* m_Str;
    UINT m_Int;
    UINT* m_IntArray;
}
我有一个非托管函数,用于创建myUnmanagedStruct结构的数组。编写正确封送数据的托管包装器的最佳方法是什么,以便将在非托管端创建的内容正确地传递回托管端?(即,我想从MyUnmanagedStructs数组生成MyManagedClass对象数组)

注:
a) 在非托管结构中创建字符串
b) 在非托管结构中创建整数向量

到目前为止,我最好的尝试是:

在管理方面:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack=1)]
    public class MyManagedClass
    {
        public MyManagedClass()
        {
            m_IntArray = new int[4];
        }

        public String m_Str;
        public int m_Int;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public int[] m_IntArray;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct UnsafeLCEArray
    {
        public int m_Int;
        public IntPtr m_CharBuf;
        public IntPtr m_IntBuf;
    }

    public unsafe class LibWrap
    {
        // Declares managed prototypes for the unmanaged function.
        [DllImport("mydll.dll", EntryPoint = "GetUnmanagedStructs")]
        public static extern voidGetUnmanagedStructs(out int size, out IntPtr outArray);
    }
typedef struct _MyUnmanagedStruct
{
   char* m_Str;
   UINT m_Int;
   UINT* m_IntArray;
} MyUnmanagedStruct;

typedef struct _UNSAFELCEARRAY
{
    char* strBuf;
    UINT intBuf; 
    UINT* intArrayBuf;
} UNSAFELCEARRAY;

extern "C" __declspec(dllexport) void GetUnmanagedStructs( int* pSize, UNSAFELCEARRAY** ppStruct )
{
    const int cArraySize = 5;
    *pSize = cArraySize;
    int numBytes = cArraySize * sizeof( MyUnmanagedStruct);
    *ppStruct = (UNSAFELCEARRAY*)CoTaskMemAlloc(numBytes);

    UNSAFELCEARRAY* pCurStruct = *ppStruct;
    char* typenamebuffer;
    char* numBuffer;
    int var = 999;
    for( int i = 0; i < cArraySize; i++, pCurStruct++ )
    {
       pCurStruct->intBuf = i+1;

       typenamebuffer = (char*)CoTaskMemAlloc( 8 );
       memcpy_s(typenamebuffer,    8, "bufABCD", 8);
       pCurStruct->strBuf = typenamebuffer;

       numBuffer = (char*)CoTaskMemAlloc( 16 );
       ++var;
       memcpy_s(numBuffer,    4, &var, 4);
       ++var;
       memcpy_s(numBuffer+4,  4, &var, 4);
       ++var;
       memcpy_s(numBuffer+8,  4, &var, 4);
       ++var;
       memcpy_s(numBuffer+12, 4, &var, 4);
       pCurStruct->intArrayBuf = (UINT*)numBuffer;
    }
 }
在非托管端:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack=1)]
    public class MyManagedClass
    {
        public MyManagedClass()
        {
            m_IntArray = new int[4];
        }

        public String m_Str;
        public int m_Int;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public int[] m_IntArray;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct UnsafeLCEArray
    {
        public int m_Int;
        public IntPtr m_CharBuf;
        public IntPtr m_IntBuf;
    }

    public unsafe class LibWrap
    {
        // Declares managed prototypes for the unmanaged function.
        [DllImport("mydll.dll", EntryPoint = "GetUnmanagedStructs")]
        public static extern voidGetUnmanagedStructs(out int size, out IntPtr outArray);
    }
typedef struct _MyUnmanagedStruct
{
   char* m_Str;
   UINT m_Int;
   UINT* m_IntArray;
} MyUnmanagedStruct;

typedef struct _UNSAFELCEARRAY
{
    char* strBuf;
    UINT intBuf; 
    UINT* intArrayBuf;
} UNSAFELCEARRAY;

extern "C" __declspec(dllexport) void GetUnmanagedStructs( int* pSize, UNSAFELCEARRAY** ppStruct )
{
    const int cArraySize = 5;
    *pSize = cArraySize;
    int numBytes = cArraySize * sizeof( MyUnmanagedStruct);
    *ppStruct = (UNSAFELCEARRAY*)CoTaskMemAlloc(numBytes);

    UNSAFELCEARRAY* pCurStruct = *ppStruct;
    char* typenamebuffer;
    char* numBuffer;
    int var = 999;
    for( int i = 0; i < cArraySize; i++, pCurStruct++ )
    {
       pCurStruct->intBuf = i+1;

       typenamebuffer = (char*)CoTaskMemAlloc( 8 );
       memcpy_s(typenamebuffer,    8, "bufABCD", 8);
       pCurStruct->strBuf = typenamebuffer;

       numBuffer = (char*)CoTaskMemAlloc( 16 );
       ++var;
       memcpy_s(numBuffer,    4, &var, 4);
       ++var;
       memcpy_s(numBuffer+4,  4, &var, 4);
       ++var;
       memcpy_s(numBuffer+8,  4, &var, 4);
       ++var;
       memcpy_s(numBuffer+12, 4, &var, 4);
       pCurStruct->intArrayBuf = (UINT*)numBuffer;
    }
 }
typedef结构\u MyUnmanagedStruct
{
char*m_Str;
国际货币基金组织;
UINT*m_IntArray;
}MyUnmanagedStruct;
typedef结构_unsafelcarray
{
char*strBuf;
UINT intBuf;
UINT*intArrayBuf;
}不安全;
外部“C”declspec(dllexport)void GetUnmanagedStructs(int*pSize,unsafelcarray**ppStruct)
{
常数int cArraySize=5;
*pSize=携带尺寸;
int numBytes=cArraySize*sizeof(MyUnmanagedStruct);
*ppStruct=(未安全阵列*)CoTaskMemAlloc(单位:字节);
不安全协议*pCurStruct=*ppStruct;
char*typenamebuffer;
char*numBuffer;
int-var=999;
对于(int i=0;iintBuf=i+1;
typenamebuffer=(char*)CoTaskMemAlloc(8);
memcpy_s(typenamebuffer,8,“bufABCD”,8);
pCurStruct->strBuf=typenamebuffer;
numBuffer=(char*)CoTaskMemAlloc(16);
++var;
memcpy_s(numBuffer,4和var,4);
++var;
memcpy_s(numBuffer+4,4和var,4);
++var;
memcpy_s(numBuffer+8,4和var,4);
++var;
memcpy_s(numBuffer+12,4和var,4);
pCurStruct->intArrayBuf=(UINT*)numBuffer;
}
}
如果我从托管对象和非托管对象中删除int向量,那么一切都会正常工作,但是对于上面的代码,int数组在返回时是未初始化的。我使用下面的函数从MyUnmanagedStructs生成MyManagedClass

        int size;
        IntPtr outArray;
        LibWrap.GetUnmanagedStructs(out size, out outArray);

        manArray = new MyManagedClass[size];
        IntPtr current = outArray;
        for (int i = 0; i < size; i++)
        {
            manArray[i] = new MyManagedClass();
            Marshal.PtrToStructure(current, manArray[i]);

            Marshal.DestroyStructure(current, typeof(sb_LCE));
            int numBytes = Marshal.SizeOf(manArray[i]);
            current = (IntPtr)((long)current + numBytes);
        }
        Marshal.FreeCoTaskMem(outArray);
int大小;
IntPtr输出阵列;
GetUnmanagedStructs(输出大小,输出数组);
manArray=新的MyManagedClass[大小];
IntPtr电流=输出阵列;
对于(int i=0;i

请原谅冗长的解释和非托管支柱被虚拟值填充的事实。这只是为了说明。

MyManagedClass.m\u IntArray
当然不应该用
marshallas(UnmanagedType.ByValArray)
标记,而应该用
LPArray
(或无,因为它默认为该行为。是的。我尝试过,但PtrToStructure语句提供了错误附加信息:无法封送类型为“MyManagedClass”的字段“m_IntArray”:无效的托管/非托管类型组合(数组字段必须与ByValArray或SafeArray成对)。尝试使
m_IntArray
成为
IntPtr
,然后使用
Marshal.Copy
将数据从中提取到托管数组中