Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[13.58.77.98] |
|
Сообщ.
#1
,
|
|
|
Есть модуль на С++ который портировать на Delphi достаточно сложно. Поэтому решил компилировать в обьектник, а потом скомпоновать с основной программой в Delphi. Этот модуль использует некоторые WinApi функции. Для примера есть функция на C++
extern "C" void __cdecl Init_Test() { GetCurrentProcess(); } После компиляции обьектног офайла и подключения его в Delphi. Выскакивают ошибки: Цитата где основной проблемой являеться имплементация системных WinApi функций. Т.к. они прописаны именно в таком виде префикс __imp__ и размер числа параметров @0 и т.п. Например, когда я компилирую какой-нибудь код в Builder C++ то в обьектном файле WinApi функции задекларированы без специфичных префиксов и окончаний. Поэтому, Delphi подцепляет их без проблем и достаточно прописать в uses windows и т.д. и тогда функции сами переопределяться. Или таким способом[dcc32 Error] Unit5.pas(22): E2065 Unsatisfied forward or external declaration: '__imp__GetCurrentProcess@0' ... 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 поддерживает этот формат. Но проблемы с окончанием названия функций. Можно было переопределить подобным образом. procedure __imp_GetCurrentProcess; external kernel32 name 'GetCurrentProcess'; но есть ещё @0. Билдер собрать необходимый модуль не может. Я так понял с++ добавляет в определение WinApi __declspec(dllimport) из-за чего появляются __imp__ и т.д. Каким образом можно самому обьявить в с++ вызов системных функций, чтобы в обьектный файл не попадали __imp__, @0... Как то статически или можно добавить .def где имена функций будут иметь соответствующий вид. Возможно есть ключ компиляции или какаето pragma. Или может в Delphi как то можно использовать их в таком виде. Возможно есть какие-то ещё варианты? Заранее спасибо за помощь! |
Сообщ.
#2
,
|
|
|
__imp__XXXX – это символ из библиотеки импорта. Он указывает ровно на тот же ординал, что и символ _XXXX. Для этого ординала линкером выделяется место под указатель на функцию XXXX в секции импорта. Сам вызов компилятор оформляет как косвенный по этому указателю, а заполняется этот указатель загрузчиком ОС, прописывая туда реальный адрес функции (который окончательно известен только после успешной загрузки и инициализации соответствующей DLL). Т.о. безразлично, какой именно символ используется, __imp__XXXX или _XXXX. Если линкер понимает импорт, конечно.
Что касается декорирования имени, то @ с суммарным количеством байт под параметры – это соглашение __stdcall. Нужно просто добавить этот модификатор к прототипу функции, чтобы компилятор передал линкеру правильное имя импортируемой функции, и тот в свою очередь корректно связал его с экспортируемым DLL именем через соответствующую библиотеку. |
Сообщ.
#3
,
|
|
|
в Visual Studio нужно было убрать
#include "windows.h" обьявить в заголовочном файле extern "C" { HANDLE __cdecl pGetCurrentProcess(VOID); } без определения. И соответственно по коду заменить GetCurrentProcess на pGetCurrentProcess. В Delphi переопределить procedure _pGetCurrentProcess; stdcall; external kernel32 name 'GetCurrentProcess'; только тогда всё собралось. Добавлено __cdecl в c++ убрал __imp__, @.. |