c# - 编码结构数组指针的方法

标签 c# arrays struct pointers marshalling

我正在从 C++ 调用函数,该函数返回一个指向结构数组的指针,我遇到了问题,因为我是这个操作/实现的新手。

我的 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;
}

问题: 如何将 C++ 函数 GetData 调用到 C#?

我当前使用 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);

当我编译它时,有一个异常: “无法编码‘返回值’:无效的托管/非托管类型组合。”

抱歉编码不好...请帮忙...

最佳答案

  • 首先,您需要记住返回值的 MarshalAs(显式或隐式)本质上意味着“将 native 结构内容复制到托管结构中”。
  • 其次,由于 CLR 编码(marshal)拆收器仅复制数据,如果您不释放在 C++ 函数中分配的内存,就会出现内存泄漏需要管理。
  • 第三,此错误主要是由于 CLR 编码(marshal)拆收器无法知道 native 代码返回的数组的长度,因为您基本上返回的是内存指针而没有长度。

如果你想保持这些内存结构不变,我强烈建议你研究一下 C++/CLI。您将能够将这些复杂类型包装到混合的 native /托管类中,从而避免您复制数据。这将帮助您将 native 代码和托管代码之间的数据编码保持在最低限度。

如果您仍想使用 C# 而不想使用 C++/CLI,则必须编写一段更智能的代码来将 native 代码返回的数据解码为托管数据。你可以看看Custom Marshaling为此。

关于c# - 编码结构数组指针的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2062088/

相关文章:

c# - NopCommerce 3.8 自定义插件 View 选项卡

Java 8 : How does `QUICKSORT_THRESHOLD=286` comes from?

php - 部分提取 php 代码的正则表达式((数组定义))

C# 调整文本框大小以适应内容

c# - 通过mailgun接收邮件

java - 不使用循环合并字符串数组/数组列表

c - 将函数传递给结构数组内的指针

struct - 在 Go 中使用结构进行原子比较和交换

c - 在 C 中的 vector 函数序列中避免(初学者)分配错误

c# - 关闭由 ShowDialog() 打开的表单