Пути к маршалу Указатель массива структур - PullRequest
3 голосов
/ 14 января 2010

Я вызываю функции из C ++, которые возвращают указатель на массив struct, и у меня возникают проблемы, так как я новичок в этой операции / реализации.

Мои коды 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);

Когда я скомпилировал это, есть исключение: «Невозможно выполнить маршализацию« возвращаемого значения »: недопустимая комбинация управляемого / неуправляемого типа.»

Извините за плохое кодирование ... Пожалуйста, помогите ...

Ответы [ 2 ]

2 голосов
/ 14 января 2010
  • Во-первых, вы должны помнить, что MarshalAs (явный или неявный) для возвращаемого значения по сути означает «копировать содержимое нативных структур в управляемые структуры».
  • Во-вторых, поскольку маршалер CLR копирует только данные, если вы не освобождаете память, выделенную для функции C ++, у вас есть утечка памяти для управления.
  • В-третьих, эта ошибка в основном связана с тем, что маршалер CLR не может узнать длину массива, возвращенного собственным кодом, так как вы в основном возвращаете указатель памяти, а не длину.

Если вы хотите сохранить эти структуры памяти как есть, я настоятельно рекомендую вам изучить C ++ / CLI. Вы сможете обернуть эти сложные типы в смешанные нативные / управляемые классы, которые позволят вам не копировать данные. Это поможет вам сохранить маршалинг данных до минимума между собственным и управляемым кодом.

Если вы все еще хотите использовать C # и не использовать C ++ / CLI, вам придется написать несколько более умный кусок кода, чтобы демонтировать данные, возвращаемые собственным кодом, в управляемые данные. Вы можете посмотреть Custom Marshaling .

0 голосов
/ 14 января 2010

Я не вижу, как среда выполнения .NET могла знать, сколько MainData выделено в GetData(...).

Рефакторинг кода C ++ для использования массива для заполнения или возврата одного MainData s.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...