Прога на дельфях и dll на асме.

Тема в разделе "WASM.WIN32", создана пользователем maradon, 21 окт 2004.

  1. maradon

    maradon New Member

    Публикаций:
    0
    Регистрация:
    30 янв 2003
    Сообщения:
    3
    Адрес:
    Russia
    Я понимаю, конечно, что вопрос про дельфи здесь оффтопик, но в дельфийских формух мне не помугут, да wasm мне ближе.



    Написал я библиотеку dll на асме, нужно мне ее импользовать в дельфийской проге. так не получается ничего. Мне нужно передать библиотечной функции строку и вернуть строку.

    1. я не понимаю как передать указатель на строку, не знаю как вернуть строку в дельфи.

    2. в результате, дельфийская прога выдает ошибку после выполнения функции dll.





    ЗЫ не стоит использоват дельфи, если можно написать на асме!
     
  2. SteelRat

    SteelRat New Member

    Публикаций:
    0
    Регистрация:
    26 авг 2004
    Сообщения:
    409
    Используй

    StrPas(Func(PChar(Stroka))); // Возвращает строку в Пасквилевском формате



    Да простит меня великий All
     
  3. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    Нужно использовать указатели. За все версии Delphi не скажу, но седьмая выполняет преобразование AnsiString<->PChar на автомате. В общем, все просто.



    Передача указателя на строку в функцию на асме: MyAsmFunction(PChar(MyString))

    Чтение строки, указатель на которую возвращает асм-функция: MyString:=MyAsmFunction, где MyAsmFunction описана как возвращающая результат типа PChar.



    Если важна длина строки (строки Delphi могут содержать в середине нулевые символы, в чем, собственно, их самая главная крутизна), то она хранится в виде DWORD непосредственно перед первым байтом строки.
     
  4. maradon

    maradon New Member

    Публикаций:
    0
    Регистрация:
    30 янв 2003
    Сообщения:
    3
    Адрес:
    Russia
    Вот смотрите дельфийский код:

    Function Mess(S: pointer):PChar; external 'mylasik.dll';

    // MyString:String;

    MyArray:='2+5='#0; //MyArray: array[0..32] of Char;

    MyString := StrPas(Mess(@MyArray));



    процедура в библиотеке:

    Mess proc aaaa:dword

    ; mov eax,aaaa

    invoke MessageBox,0,eax,eax,MB_OK

    mov eax,offset mmmm ; mmmm db "test",0

    ret

    Mess endp



    Получается в функции Mess регистр eax уже содержит указатель на сточку, а по адрессу аааа ее нет.

    да и эта строчка MyString := StrPas(Mess(@MyArray));

    вроде должна работать, а реале нет.
     
  5. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    А с соглашениями о способе передачи параметров точно ничего не напутано?
     
  6. SteelRat

    SteelRat New Member

    Публикаций:
    0
    Регистрация:
    26 авг 2004
    Сообщения:
    409
    stdcall забыл :)
     
  7. SteelRat

    SteelRat New Member

    Публикаций:
    0
    Регистрация:
    26 авг 2004
    Сообщения:
    409
    Function Mess(S: pointer):PChar; stdcall external 'mylasik.dll';

    Вроде так :)
     
  8. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев
    function Mess(S: String): String; stdcall;

    implementation

    function Mess; external 'mylasik.dll' name 'Mess';
     
  9. maradon

    maradon New Member

    Публикаций:
    0
    Регистрация:
    30 янв 2003
    Сообщения:
    3
    Адрес:
    Russia
    Во работает! большое человеческое шпасибо! сам бы долго мучался %)

    Только не понял зачем нужен implementation
     
  10. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    maradon

    "Только не понял зачем нужен implementation"

    masquer привел пример, когда функция Мess объявлена в interface и может быть доступна для других модулей. Если этого не нужно, то просто объявляешь

    implementation

    function Mess(S:PChar):PChar;stdcall;external 'mylasik.dll' name 'Mess';



    Единственное замечание к коду masquer - это использование string. Как известно, при работе с dll передавать AnsiString не рекомедуется или нужно это делать осторожно (использовать в uses ShareMem или следить за тем, чтобы последний экземпляр строки удалялся только в "родном" модуле). Иначе можно нарваться на EAccessViolation или EInvalidPointer, т.к. без ShareMem у приложения и dll разные хипы.



    CyberManiac

    "За все версии Delphi не скажу, но седьмая выполняет преобразование AnsiString<->PChar на автомате"

    Прямое присваивание работает с Delphi 3, поэтому конечно StrPas - это анахронизм. И тип PChar совместим c array[0..X] of Char, поэтому если объявляешь Mess(S:PChar), то дальше просто
    Код (Text):
    1. //MyString:String;
    2. //MyArray: array[0..31] of Char; {а здесь лучше 31, а не 32 - иначе min 3 байта - на ветер (на align)}
    3. MyString := Mess(MyArray);
     
  11. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев