Calling conversion

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Calling conversion

Сообщение FedeX » 03.11.2008 13:37:45

Пытаюсь перевести на Паскаль заголовки libgles_cm.dll библиотечки под Win32 (емуляция OpenGL ES под Win32), но столкнулся с тем, что часть функций имеет толи какой-то нестандартный Calling conversion, то ли вообще как-то не так описаны. Для этой же библиотеки только WinCE версии я уже вроде бы перевёл заголовки - там все функции cdecl. Всё вроде работает. В сишных заголовках под Win32 стоят такие макросы:
Код: Выделить всё
#if defined(AEE_SIMULATOR)

#define __GL_EXPORTS

#endif



#ifdef _WIN32

#   ifdef __GL_EXPORTS

#       define GL_API __declspec(dllexport)

#   else

#       define GL_API __declspec(dllimport)

#   endif

#else

#   ifdef __GL_EXPORTS

#       define GL_API

#   else

#       define GL_API extern

#   endif

#endif



#define GL_APIENTRY



#ifndef GLAPI

#   define GLAPI GL_API

#endif

, а функции обьявлены например как:
#ifdef __cplusplus

extern "C" {

#endif
GLAPI EGLint APIENTRY eglGetError();
#ifdef __cplusplus

}

#endif
но когда я обьявляю функции как
function eglGetError:EGLint;stdcall;external egl_lib name 'eglGetError';
при запуске приложения пишет, что точка входа в процедуру не найдена. Причём не все процедуры не находяться, а только те что начинаються на eglххх. Я попробовал открыть длл в написанной на Делфи утилитке, что используя модуль imagehlp отображает экспортируемые функции. В ней я увидел интересную вещь - функции, точка входа которых не найдена отображаються как напр. _eglGetError@0 , тоесть почему-то со знаком "_" в начале и с указанием общего размера передаваемых параметров после символа "@". Что это может быть? Какие-то с++-ные методы чтоли? Как их обьявить на Паскале?
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Re: Calling conversion

Сообщение Sergei I. Gorelkin » 03.11.2008 14:57:20

Это обычный stdcall (если я не путаю. Если путаю, то cdecl), только библиотека немного по-больному слинкована.
Объявить, наверное, можно, указав это кривое имя после name.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Calling conversion

Сообщение FedeX » 03.11.2008 15:32:34

Да - действительно, если после name указать это странное имя, то точка входа находиться. Ещё всё не перевёл, но наверно дольше проблем не будет. Спасибо.
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Re: Calling conversion

Сообщение VAshot » 23.02.2009 15:43:41

Есть библиотека аписанная на С, dll и lib файл.
Вот так вызов идет из программы на С:
Код: Выделить всё
#pragma once

#include <iostream>
#include <stdio.h>
#include <tchar.h>

_declspec(dllimport) long GetHeaderSecondArg(TCHAR* fileName);

#include "HeadReader_demo.h"

int _tmain(int argc, _TCHAR* argv[])
{
   TCHAR* fileName;
   fileName = L"N5_18062008_17 22 12.bn1";

   GetHeaderSecondArg(fileName);

   return 0;
}


А вот так пытаюсь вызвать я:
Код: Выделить всё
interface

uses
  function GetHeaderSecondArg(filename: PWideString): Integer; cdecl; external 'BINFileReader_demo.dll' name 'GetHeaderSecondArg';           


При запуске ошибка: "Не могу найти точку входа".
Это я делаю что-то не то или в библиотеке С надо переделать? Исходника, пока, библиотеки нет.
Аватара пользователя
VAshot
постоялец
 
Сообщения: 128
Зарегистрирован: 01.11.2007 12:31:21
Откуда: Пермь

Re: Calling conversion

Сообщение FedeX » 23.02.2009 16:41:50

Да, скорее всего это тоже что и у меня было..
Надо перекомпилировать саму длл-ку, и везде в экспортируемых функциях прописать extern C (или что-то вроде этого)..
Если исходников либы нет, то возможно поможет какая-нибудь прога вроде ADLLExport.. Посмотреть, какие там (в длл) имена функций через прогу и так их и описать в паскалевских хедерах.. А ещё проще обращаться к функциям по индексам..
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Re: Calling conversion

Сообщение VAshot » 25.02.2009 18:03:55

Вроде получилось, когда результат передается в Result.
А как подключить и вызвать такую функцию?
Код: Выделить всё
bool GetHeaderFirstArg(TCHAR* fileName, char* retVal);

Функция принимает два аргумента: указатель строку типа TCHAR* (в данной сборке этот тип означает указатель на "широкие" строки) и указатель на строку типа char* (указатель на обычную строку).
fileName - имя файла, откуда необходимо получить данные,
retVal - указатель на строку в памяти, куда необходимо записать данные
Функция записывает в retVal первую строку заголовка файла и возвращает true в случае успеха.


Перебрад несколько способов, что-то делаю не так. Не направите на путь истинный?
Аватара пользователя
VAshot
постоялец
 
Сообщения: 128
Зарегистрирован: 01.11.2007 12:31:21
Откуда: Пермь

Re: Calling conversion

Сообщение GrayEddy » 25.02.2009 18:17:23

Скорее так:
Код: Выделить всё
function GetHeaderFirstArg(fileName: WideString; retVal: PChar): Boolean
GrayEddy
постоялец
 
Сообщения: 375
Зарегистрирован: 06.05.2005 09:37:56

Re: Calling conversion

Сообщение FedeX » 25.02.2009 18:58:50

Помойму так:
function GetHeaderFirstArg(fileName: PWideChar; retVal: PAnsiChar): Boolean;cdecl; external 'BINFileReader_demo.dll' index ...;

..хех.. хотя возможно и так:
function GetHeaderFirstArg(fileName: PWideChar; var retVal: PAnsiChar): Boolean;cdecl; exter...

Вообще к либе должны быть как минимум какие-то доки. И в них должны описываться такие подробности... Просто если учесть что во второй параметр функция будет возвращать значение, то логично что буфер для строки либо должен быть уже выделен либо он должен быть выделен функцией .. Во втором случае логичен "var", в первом - нет..
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Re: Calling conversion

Сообщение VAshot » 25.02.2009 20:58:20

Работает (что и логично и правильно) так: "fileName: PWideString".

Вот так работает, только я не знаю, корректно это или нет. Впервые использую указатели самостоятельно.
Код: Выделить всё
  function GetNumOfStrings(fileName: PWideString): Integer; cdecl; external ...
  function GetHeaderFirstArg(fileName: PWideString; retVal: PAnsiChar): Boolean; cdecl; external ...
//---------------------------------------------
var
  WS : WideString;
  PS : PAnsiChar;

  Count: Integer;
begin
  WS:='E:\folder\N5_18062008_17 22 12.bn1';
//-----
  Count := GetNumOfStrings(PWideString(WS));
  ShowMessage( IntToStr(Count) );
//-----
  GetMem(PS, SizeOf(AnsiChar));
  GetHeaderFirstArg(PWideString(WS), PS);
  ShowMessage( PS^ );
  Freemem(PS);
//-----
end;
Аватара пользователя
VAshot
постоялец
 
Сообщения: 128
Зарегистрирован: 01.11.2007 12:31:21
Откуда: Пермь

Re: Calling conversion

Сообщение FedeX » 25.02.2009 22:23:09

Вообще-то не должно работать... :?
GetMem(PS, SizeOf(AnsiChar));
Это должно всегда создавать буфер величиной в один байт (один символ)...
Если функция и должна считывать из файла только один символ, то правитьно, если должна считывать больше - то не правильно..
Что показывает ShowMessage( PS^ ); ? Один символ? А так в остальном правильно..
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Re: Calling conversion

Сообщение VAshot » 25.02.2009 22:27:33

Да, пожалуй надо домножить на число символов
Аватара пользователя
VAshot
постоялец
 
Сообщения: 128
Зарегистрирован: 01.11.2007 12:31:21
Откуда: Пермь

Re: Calling conversion

Сообщение GrayEddy » 25.02.2009 23:27:07

Тут несколько вариантов, тоже подключал в свое время сишную либу от кассового аппарата, поднял исходники, тогда по аналогии

Вариант 1:
Код: Выделить всё
var
  s: string;
...
GetHeaderFirstArg(PWideString(WS), PChar(s));
...


Вариант 2 (более правильный, что ли):
Код: Выделить всё
var
  s: PChar;
...
s := StrAlloc(1024); // Занимаем память
s := StrCopy(s, 'COM1');
GetHeaderFirstArg(PWideString(WS), PChar(s));
StrDispose(s); // Отдаем память
...
GrayEddy
постоялец
 
Сообщения: 375
Зарегистрирован: 06.05.2005 09:37:56


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Рейтинг@Mail.ru