Маршал 2 IntPtr в той же функции?

0

Я хотел бы знать способ, как маршал 2 класса, которые я сделал в C++ на языке С#. (ссылка на учебник была бы идеальной, я попытался сделать это для себя сам, но мои знания английского языка - это не продвижение, поиск правильной вещи. Я новичок в маршалинге от C++ до С#)

В общем, у меня есть что-то вроде этого:

C++

EXPORT_API CarClass* DLL_AddCar();
EXPORT_API CarWheel* DLL_AddWheel();
EXPORT_API void DLL_GiveWheelToCar(CarClass* car,CarWheel* wheel);

С#

public class Car
{       
    #region Members     
    private IntPtr nativeCarObject; 
    #endregion Members

    public Car()
    {           
        this.nativeCarObject = Sim.DLL_AddCar();

    }

    // ---> this part is not working
    //#region Wrapper methods           
    //public void GiveWheel(Wheel myWheel){Sim.DLL_GiveWheelToCar(this.nativeCarObject,myWheel);}
    //#endregion Wrapper methods
}

public class Wheel
{       
    #region Members     
    private IntPtr nativeCarObject; 
    #endregion Members

    public Wheel()
    {           
        this.nativeCarObject = Sim.DLL_AddWheel();

    }
}   

internal class Sim
{
    public const string pluginName = "MyDLL";   

    #region PInvokes
    [DllImport(pluginName)] public static extern IntPtr DLL_AddCar();
    [DllImport(pluginName)] public static extern IntPtr DLL_AddWheel();
    [DllImport(pluginName)] public static extern void DLL_GiveWheelToCar(IntPtr car,IntPtr wheel);
    #endregion PInvokes 
}

Теперь мой вопрос: где я должен использовать "DLL_GiveWheelToCar"? Метод, который я попробовал, закомментирован, потому что он не работал, это логическая ошибка или мне нужно изменить способ маршалинга?

Спасибо за совет.

Теги:
dll
pinvoke
marshalling

1 ответ

0
Лучший ответ
public void GiveWheel(Wheel myWheel){
    Sim.DLL_GiveWheelToCar(this.nativeCarObject, myWheel);
}

Здесь вы передаете myWheel который относится к типу Wheel к функции, которая ожидает IntPtr. Вам нужно передать личное поле класса Wheel, которое в настоящее время (неверно) называется nativeCarObject.

Другие пункты:

  1. Как я уже nativeCarObject член nativeCarObject of Wheel должен быть переименован в nativeWheelObject.
  2. DLL выглядит так, как будто она использует cdecl вызове cdecl. Вы должны указать это в своих объявлениях p/invoke.
  3. Похоже, вы код теряет объекты, которые поставляется DLL. Я подозреваю, что вам нужно снабдить некоторых помощников.

Код может выглядеть примерно так:

public class Car
{
    public readonly IntPtr nativeCarObject = Sim.DLL_AddCar();

    public void GiveWheel(Wheel myWheel)
    {
        Sim.DLL_GiveWheelToCar(this.nativeCarObject, myWheel.nativeWheelObject);
    }    
}

public class Wheel
{
    public readonly IntPtr nativeWheelObject = Sim.DLL_AddWheel();
}

internal class Sim
{
    public const string pluginName = "MyDLL";

    [DllImport(pluginName, CallingConvention=CallingConvention.Cdecl)]
    public static extern IntPtr DLL_AddCar();
    [DllImport(pluginName, CallingConvention = CallingConvention.Cdecl)]
    public static extern IntPtr DLL_AddWheel();
    [DllImport(pluginName, CallingConvention = CallingConvention.Cdecl)]
    public static extern void DLL_GiveWheelToCar(IntPtr car, IntPtr wheel);
}

Этот код по-прежнему теряет эти объекты. Я позволю тебе разобраться.

  • 0
    Спасибо! Я внес изменения. Что касается самого объекта, я сделал метод GetObject, который возвращает его IntPtr. Можно ли было бы как-то извлечь из IntPtr?
  • 0
    Я не думаю, что имеет смысл выводить из IntPtr .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню