Конференция "Основная" » Дельфийский интерфейс для Сишных прог [D7, WinXP]
 
  • andreil © (09.06.08 00:11) [0]
    Значит так. Пишу ДЛЛку на Дельфи, в которой присутствуют интерфейсы.
    Эта библиотека юзается сторонними программами с участием интерфейсов.
    Есть часть исходников этой же ДЛЛки на С++. Вот куски, касающиеся интерфейсов:
    class CSteamInterface006 : public CSteamInterface005
    {
    public:
    CSteamInterface006();
    ~CSteamInterface006();

    virtual int FindServersNumServers(unsigned int arg1);
    virtual int FindServersIterateServer(int arg1, int arg2, char *szServerAddress, unsigned int uServerAddressChars);
    virtual int FindServersGetErrorString();
    }
    ;


    unsigned int _f
    {
    static CSteamInterface006 SteamInterface006;
    return (unsigned int)&SteamInterface006;
    }



    Вопрос - как это переделать на Дельфи? Просто я в интерфейсах - нуб, а тут еще вопрос - получится ли солвместить Си с Дельфи?
  • DrPass © (09.06.08 01:22) [1]
    Что-то я не увидел тут никаких интерфейсов. Обычный сишный класс, разве что слово Interface в названии присутствует
  • andreil © (09.06.08 10:10) [2]
    Я в Си нуб, о чем и сказал, но мне на инглиш форуме сказали, что там именно интерфейс и в этом коде:
    unsigned int _f
    {
    static CSteamInterface006 SteamInterface006;
    return (unsigned int)&SteamInterface006;
    }


    идет передача Сишной программе интерфейса.
    Если делать в Дельфи CSteamInterface006 классом, то нифига не работает, поскольку компилер показывает, что процедуры этого класса не собраны в ДДЛку. + если все-таки оставить его, то при вызове этого интерфейса вылазит ошибка чтения памяти :( в том районе, где ничего нету
    Если же сделать именно интерфейс, то ошибка памяти есть, но в районе, где находится неизвестный код (судя по всему - основной программы)
  • Loginov Dmitry © (09.06.08 10:47) [3]
    > но мне на инглиш форуме сказали, что там именно интерфейс
    > и в этом коде:
    > unsigned int _f
    > {
    > static CSteamInterface006 SteamInterface006;
    > return (unsigned int)&SteamInterface006;
    > }
    > идет передача Сишной программе интерфейса.


    Тут передается просто ссылка на созданный (причем static) объект. Причем здесь интерфейсы?

    Переписать - не проблема (наверно:). Один в один переписывай весь код на дельфи.
    В ЕХЕ тебе нужно создать аналогичный класс, только абстрактный. Например:

    TSteamInterface006 = class(TSteamInterface005)
    public  
     function FindServersNumServers(arg1: Cardinal): Integer; virtual; stdcall; abstract;
     function FindServersIterateServer(arg1, arg2: Integer; szServerAddress: PChar; uServerAddressChars: Integer): Integer; virtual; stdcall; abstract;
     function FindServersGetErrorString(): Integer; virtual; stdcall; abstract;
    end;



    Далее объявляешь переменную
    var
     ASteamInterface: TSteamInterface006;



    Получаешь ссылку на объект:
    Cardinal(ASteamInterface) := _f();



    И работаешь с объектом через абстрактные методы. В рельности же будут вызваны функции из DLL.

    Не уверен на 100%, что удасться совместить код С++ и Дельфи, однако предполагаю, что получится. Виртуальные и абстрактные методы во всех языках, поддерживающих интерфейсы, реализованы одинаково (таблица виртуальных методов имеет везде одинаковое смещение и т.д.) (это имхо, т.к. все - по памяти).

    Однако я не понял, нужно ли тебе совмещать С++ и Дельфи, или же просто переписать все на Дельфи?
  • Игорь Шевченко © (09.06.08 11:10) [4]

    > public CSteamInterface005


    описание в студию
  • jack128_ (09.06.08 11:25) [5]

    > > public CSteamInterface005
    >
    >
    > описание в студию
    >


    Зуб даю, что примерно так начинается:
    class CSteamInterface005 : public CSteamInterface004

    :-))
    > Что-то я не увидел тут никаких интерфейсов.

    насколько я понимаю бинарная структура интерфейсов и дельфийских и сишных классов - совпадает.  главное чтоб первые три элемента VMT базового предка классов имели ссылки на AddRef/Release/QueryInterface
  • palva © (09.06.08 11:58) [6]
    На самом деле (сужу по старым версиям, новых версий не знаю) в языке С++ нет интерфейсов. Слово interface является синонимом слова class, а интерфейсом называется класс, который не содержит полей, а только виртуальные абстрактные методы. Чтобы класс вел себя как интерфейс требуется писать дополнительный код.
  • jack128_ (09.06.08 13:16) [7]

    > На самом деле (сужу по старым версиям, новых версий не знаю)
    > в языке С++ нет интерфейсов.

    естественно нет. они не нужны так как

    > бинарная структура интерфейсов и дельфийских и сишных классов

    А вот в дельфи интерфейсы нуны, так как классы не поддерживают множественное наследование..
  • Dimka Maslov © (09.06.08 13:38) [8]
    Есть такая штука, называется COM

    Сишная библиотека делается COM-сервером, в котором реализован интерфейс. Программа на дельфе - клиент, обращающийся к серверу и получающий указатель на интерфейс. И всё. Не надо использовать никаких кривых абстрактных классов и прочей мути. Если нет желания прописывать длл в реестр, то можно обойтись и без этого. Тогда сервер должен экспортировать одну нестандартную функцию создания объекта.
  • DrPass © (09.06.08 15:16) [9]
    Я ж так понимаю, у него хостовая часть приложения уже "дана свыше" и на Ц++ (собственно, и догадаться несложно, о каком приложении идет речь -Steam). А он, читая прилагаемые к ней Цплюсплюсные хедеры, пытается сочинить клиента на Delphi.
  • andreil © (09.06.08 17:21) [10]
    Я вообщето не сочиняю клиента Стима, а делаю обертку к эмулятору, что требуют несколько проектов. Протсо без этого надо изучать кучу форматов файлов, а так - все нихтяк :)
    И все-бы хорошо, но игры, в которых этот эмуль рабоает, взаимодействуют только через эти интерфейсы. Если бы были просто вызовы, я бы сюда не обращался, тк заголовки всех 156функций уже переведены :)
    Но эти интерфейсы.... :( Никак не могу заставить работать и все тут :(
  • andreil © (09.06.08 17:24) [11]

    > Сишная библиотека делается COM-сервером, в котором реализован
    > интерфейс. Программа на дельфе - клиент

    Я вообщето пишу Дельфийскую библиотеку для Сишной проги, а не наоборот ;)
    Я просто говорои, что есть часть исходников этой библиотеки на Си
  • andreil © (09.06.08 21:17) [12]
    Итак, вроде как со всем разобрался.
    Но вот вопрос - как передать интерфейс?
    В Сишной ДЛЛке:
    return (unsigned int)&SteamInterface006;


    В моей ДЛЛке:
    SteamInterface006:=CSteamInterface006.Create;
         result:=uint(@SteamInterface006);


    Правильно, или надо както по-другому?
  • Loginov Dmitry © (09.06.08 22:30) [13]
    > Правильно, или надо както по-другому?


    Собаку убери.

    Еще: конструкции получились неравноценны. В С++ у тебя объект создается только 1 раз. А в Дельфи - при каждом вызове экспортируемой функции.
  • Dimka Maslov © (10.06.08 10:57) [14]

    > Я вообщето пишу Дельфийскую библиотеку для Сишной проги,
    >  а не наоборот ;)


    Тогда тем более надо библиотеку делать COM-сервером. Кстати на Delphi это сделать немного проще.
  • andreil © (10.06.08 15:18) [15]

    > Собаку убери.

    ОК

    > Тогда тем более надо библиотеку делать COM-сервером. Кстати
    > на Delphi это сделать немного проще.

    Тыкни в место, где рассказывается об этом, а то я СОМ не изучал :(

    > Еще: конструкции получились неравноценны. В С++ у тебя объект
    > создается только 1 раз. А в Дельфи - при каждом вызове экспортируемой
    > функции.

    Может так?:
    if SteamInterface006=nil then
     SteamInterface006:=CSteamInterface006.Create;
         result:=uint(SteamInterface006);

  • andreil © (10.06.08 15:21) [16]
    Хм, все-равно ЕРРОР :(
    Посмотрите, может я объявил не правильно?:
    CSteamInterface006 = class (CSteamInterface005)
    ...
    CSteamInterface005 = class (CSteamInterface004)
    ...
    CSteamInterface004 = class (CSteamInterface003)
    ...
    CSteamInterface003 = class (TInterfacedObject)


    ?
  • DrPass © (10.06.08 16:15) [17]

    > CSteamInterface003 = class (TInterfacedObject)

    Скорее всего CSteamInterface003 = class (TObject)
    Чего ты за слово "интерфейс" уцепился? Нет там никаких интерфейсов, не лепи их. Это просто ссылки на классы.
  • andreil © (10.06.08 17:07) [18]

    > Скорее всего CSteamInterface003 = class (TObject)

    Сделал. Эффекта 0.
    Скинул полные исходники того, что наработал, может кто поможет :(
    http://ifolder.ru/6925349
  • andreil © (10.06.08 17:11) [19]
    Забыл сказать. Проблемный код находится в Steam_Interface.pas (функция "function _f(cszSteamInterfaceVersion: pChar): uint; export; cdecl;").
 
Конференция "Основная" » Дельфийский интерфейс для Сишных прог [D7, WinXP]
Есть новые Нет новых   [134491   +8][b:0][p:0.002]