На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
  
> Использование obj в Delphi , Visual Studio 2017, Delphi XE 10.1
    Есть модуль на С++ который портировать на Delphi достаточно сложно. Поэтому решил компилировать в обьектник, а потом скомпоновать с основной программой в Delphi. Этот модуль использует некоторые WinApi функции. Для примера есть функция на C++

    ExpandedWrap disabled
      extern "C" void __cdecl Init_Test()
      {
          GetCurrentProcess();
      }


    После компиляции обьектног офайла и подключения его в Delphi. Выскакивают ошибки:

    Цитата
    [dcc32 Error] Unit5.pas(22): E2065 Unsatisfied forward or external declaration: '__imp__GetCurrentProcess@0'
    где основной проблемой являеться имплементация системных WinApi функций. Т.к. они прописаны именно в таком виде префикс __imp__ и размер числа параметров @0 и т.п. Например, когда я компилирую какой-нибудь код в Builder C++ то в обьектном файле WinApi функции задекларированы без специфичных префиксов и окончаний. Поэтому, Delphi подцепляет их без проблем и достаточно прописать в uses windows и т.д. и тогда функции сами переопределяться. Или таким способом

    ExpandedWrap disabled
      ...
      procedure __chmod; cdecl; external 'msvcrt.dll' name '_chmod';
      procedure _calloc; cdecl; external 'msvcrt.dll' name 'calloc';
      procedure _gmtime; cdecl; external 'msvcrt.dll' name 'gmtime';
      ...

    чтобы не возникало ошибки.
    Цитата
    [dcc32 Error]E2065 Unsatisfied forward or external declaration:

    но Builder C++ (bcc) и создаёт omf формат. А Visual Studio (cl) coff. Благо Delphi в XE поддерживает этот формат. Но проблемы с окончанием названия функций. Можно было переопределить подобным образом.

    ExpandedWrap disabled
      procedure __imp_GetCurrentProcess; external kernel32 name 'GetCurrentProcess';


    но есть ещё @0.

    Билдер собрать необходимый модуль не может.

    Я так понял с++ добавляет в определение WinApi __declspec(dllimport) из-за чего появляются __imp__ и т.д.

    Каким образом можно самому обьявить в с++ вызов системных функций, чтобы в обьектный файл не попадали __imp__, @0... Как то статически или можно добавить .def где имена функций будут иметь соответствующий вид. Возможно есть ключ компиляции или какаето pragma. Или может в Delphi как то можно использовать их в таком виде. Возможно есть какие-то ещё варианты?

    Заранее спасибо за помощь!
      __imp__XXXX – это символ из библиотеки импорта. Он указывает ровно на тот же ординал, что и символ _XXXX. Для этого ординала линкером выделяется место под указатель на функцию XXXX в секции импорта. Сам вызов компилятор оформляет как косвенный по этому указателю, а заполняется этот указатель загрузчиком ОС, прописывая туда реальный адрес функции (который окончательно известен только после успешной загрузки и инициализации соответствующей DLL). Т.о. безразлично, какой именно символ используется, __imp__XXXX или _XXXX. Если линкер понимает импорт, конечно.
      Что касается декорирования имени, то @ с суммарным количеством байт под параметры – это соглашение __stdcall. Нужно просто добавить этот модификатор к прототипу функции, чтобы компилятор передал линкеру правильное имя импортируемой функции, и тот в свою очередь корректно связал его с экспортируемым DLL именем через соответствующую библиотеку.
        в Visual Studio нужно было убрать
        ExpandedWrap disabled
          #include "windows.h"

        обьявить в заголовочном файле
        ExpandedWrap disabled
          extern "C"
          {
             HANDLE __cdecl pGetCurrentProcess(VOID);
          }

        без определения. И соответственно по коду заменить GetCurrentProcess на pGetCurrentProcess.

        В Delphi переопределить
        ExpandedWrap disabled
          procedure _pGetCurrentProcess; stdcall; external kernel32 name 'GetCurrentProcess';

        только тогда всё собралось.

        Добавлено
        __cdecl в c++ убрал __imp__, @..
        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
        0 пользователей:


        Рейтинг@Mail.ru
        [ Script execution time: 0,0241 ]   [ 16 queries used ]   [ Generated: 28.03.24, 08:11 GMT ]