Вызов неуправляемой функции, которая возвращает объект по значению - PullRequest
1 голос
/ 03 мая 2019

Предположим следующее:

Давайте получим класс C ++:

class ExampleClass
{
 private:
    int var1;
 public:
    void DoSomething();
}

Предположим также следующую функцию C ++, которую мы хотим вызвать из приложения .NET Core с помощью PInvoke или с помощью EmitCalli:

extern "C" ExampleClass CreateObject()

Итак, функция C ++ возвращает экземпляр класса ExampleClass по значению.Есть ли способ получить этот экземпляр на управляемой части в виде байтового массива (при условии, что размер ExampleClass известен).

Как я помню, в большинстве нативных соглашений о вызовах x86 (x64) функции C ++, которые возвращают структуры, фактически имеют указатель на структуру для заполнения в качестве одного из параметров.Будет ли этот совет работать с NET Core: выделить байтовый массив в управляемой части и передать указатель в качестве первого параметра для неуправляемого вызова?

Спасибо!

1 Ответ

1 голос
/ 03 мая 2019

в C ++

ExampleClass CreateClass();

вернет блок байтов sizeof(ExampleClass), а при отсутствии виртуальных членов и наследования он будет простым объектом и эквивалентен тому же определению структуры (подробнее об этом здесь: Структура объекта C ++ в памяти против структура )

P / Invoke marshaller должен быть в состоянии справиться с этим без проблем.

Это не IntPtr, это фактический блок памяти для C и C ++. Эквивалент IntPtr будет

ExampleClass * CreateClass();

Я не уверен, почему он возвращает экземпляр вместо указателя, но у них, вероятно, были свои причины.

поэтому, если вы определите это

public struct ExampleClass
{
    public int Var1;
}

у вас должно быть все в порядке (за исключением того, что структура класса более сложна, вам нужно проверить, что такое компоновка в компиляции C ++, в частности, для заполнения. Например, класс с 2 bool s может дать размер 16 в некоторых заполнениях).

подробнее здесь:

...