简体   繁体   English

如何构造一个结构数组的指针

[英]Ways To Marshal A Pointer of Array of Struct

I'm calling functions from C++ that returns a pointer to an array of struct and I'm having problems since I'm new to this operation/implementation. 我正在调用C ++中的函数,它返回一个指向struct数组的指针,因为我是这个操作/实现的新手,所以我遇到了问题。

My C++ codes: 我的C ++代码:

// My C++ Structs

typedef struct _MainData {

    double      dCount;
    DataS1          *DS1;
    int     iCount1;
    DataS2          *DS2;
    int     iCount2;
}MainData;

typedef struct _DataS1 {

    unsigned int    uiCount1;   
    unsigned int    uiCount2;   
    int     iCount;
    void        *pA;    
    void        *pB;    

} DataS1;

typedef struct _DataS2 {

    unsigned int    uiCount1;   
    unsigned int    uiCount2;               
    unsigned int    uiCount3;               
    unsigned int    uiCount4;           
    double      dCount; 
    int     iCount1;                    
    char        strLbl[64];
} DataS2;

// My C++ Function

MainData* GetData(const int ID)
{

        MainData* mData;
        int iLength = Get_Count();
    mData = new MainData[iLength];
        for(int x = 0;x < VarCounter; x++)
        {
            // Codes here assign data to mData[x]
        }
        return mData;
}

Question: How can I call the C++ function GetData to C#? 问题:如何将C ++函数GetData调用到C#?

My current codes in C# are: 我目前在C#中的代码是:

[DllImport(".\\sdata.dll")]
[return: MarshalAs(UnmanagedType.LPArray)]
private static unsafe extern MainData[] GetData(int ID);


// The struct MainData in my C# side is already "Marshalled"...

//My function call is here:
MainData[] SmpMapData = GetData(ID);

When I compiled it, there's an exception: "Cannot marshal 'return value': Invalid managed/unmanaged type combination." 当我编译它时,有一个例外:“无法编组'返回值':无效的托管/非托管类型组合。”

Sorry for the poor coding... Please help... 抱歉编码不好...请帮忙......

  • First, you need to remember that MarshalAs (explicit or implicit) for the return value essentially means "copy native structures content into managed structures". 首先,您需要记住,返回值的MarshalAs(显式或隐式)实质上意味着“将本机结构内容复制到托管结构中”。
  • Second, since the CLR marshaler only copies the data, if you do not free the memory you're allocated in the C++ function, you've got a memory leak to manage. 其次,由于CLR封送器只复制数据,如果你没有释放你在C ++函数中分配的内存,你就会有内存泄漏需要管理。
  • Third, this error is mainly due to the fact that the CLR marshaler has no way of knowing the length of the array returned by the native code, since you're basically returning a memory pointer and no length. 第三,这个错误主要是由于CLR封送程序无法知道本机代码返回的数组的长度这一事实,因为你基本上是返回一个内存指针而没有长度。

If you want to keep these memory structures as-is, I strongly suggest you to look into C++/CLI. 如果你想保持这些内存结构,我强烈建议你研究一下C ++ / CLI。 You'll be able to wrap those complex types into mixed native/managed classes that will avoid you to copy the data around. 您将能够将这些复杂类型包装到混合的本机/托管类中,从而避免复制数据。 This will help you keep the data marshaling to the bare minimum between native and managed code. 这将帮助您将本地和托管代码之间的数据编组保持在最低限度。

If you still want to use C# and no C++/CLI, you'll have to write a somehow smarter piece of code to unmarshal the data returned by the native code into managed data. 如果您仍然想要使用C#而不是C ++ / CLI,则必须编写一些更智能的代码来将本机代码返回的数据解组为托管数据。 You can look into Custom Marshaling for that. 您可以查看Custom Marshaling

I don't see how the .NET runtime could possibly know how many MainData are allocated in GetData(...) . 我没有看到.NET运行时如何知道在GetData(...)中分配了多少MainData

Refactor your C++ code to consume an array to populate or return single MainData s. 重构您的C ++代码以使用数组来填充或返回单个MainData

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM