Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Процедурный тип для вызова внешней подпрограммы


Автор: Чупакабро 15.6.2011, 22:10
Hi all!
Нужно вот эту радость перевести с С на Delphi:

Код

typedef void (APIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
typedef void (APIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
typedef void (APIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
typedef void (APIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, int size, const GLvoid *data, GLenum usage);

PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL; // VBO Name Generation Procedure
PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL; // VBO Bind Procedure
PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL; // VBO Data Loading Procedure
PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL;


Смысл в чем: объявляются процедурные типы, потом процедурные переменные. Далее идут вызовы процедур (я их здесь не привел).
Тут одна маленькая загвоздочка: эти процедуры описаны не в моей программе, а в драйвере видеокарты (насколько я понял). И их адреса возвращает функция wglGetProcAddress. Адреса-то она возвращает, только при попытке вызова процедур по этим адресам происходит исключение Access violation.

мой вариант перевода такой:
Код

  PFNGLGENBUFFERSARBPROC=procedure(n:GLsizei;buffers:pGLuint);
  PFNGLBINDBUFFERARBPROC=procedure(target:GLEnum;buffer:GLuint);
  PFNGLBUFFERDATAARBPROC=procedure(target:GLenum;size:GLsizei;data:pGLuint;usage:GLenum);
  PFNGLDELETEBUFFERSARBPROC=procedure(n:glsizei;buffers:pgluint);

var
  glGenBuffers:^PFNGLGENBUFFERSARBPROC=nil;
  glBindBuffer:^PFNGLBINDBUFFERARBPROC=nil;
  glBufferData:^PFNGLBUFFERDATAARBPROC=nil;
  glDeleteBuffers:^PFNGLDELETEBUFFERSARBPROC=nil;

и вот не пойму, в чем загвоздка, так как я не очень хорошо знаю Delphi, а уж С знаю совсем плохо.

Автор: Чучмек 15.6.2011, 22:26

 без ^ !!!
Код

var
  glGenBuffers:PFNGLGENBUFFERSARBPROC=nil;
  glBindBuffer:PFNGLBINDBUFFERARBPROC=nil;
  glBufferData:PFNGLBUFFERDATAARBPROC=nil;
  glDeleteBuffers:PFNGLDELETEBUFFERSARBPROC=nil;

Автор: Чупакабро 15.6.2011, 22:32
Спасибище ОГРОМНОЕ!!!
Вот я тупой, процедурный тип - сам по себе указатель!
Заработало!))
p.s. ну и stdcall само собой...

Автор: Чучмек 15.6.2011, 22:34
Кроме того может быть  stdcall
Код

  PFNGLGENBUFFERSARBPROC=procedure(n:GLsizei;buffers:pGLuint);stdcall;
  PFNGLBINDBUFFERARBPROC=procedure(target:GLEnum;buffer:GLuint);stdcall;
  PFNGLBUFFERDATAARBPROC=procedure(target:GLenum;size:GLsizei;data:pGLuint;usage:GLenum);stdcall;
  PFNGLDELETEBUFFERSARBPROC=procedure(n:glsizei;buffers:pgluint);stdcall;


на будующее...

Автор: Чупакабро 15.6.2011, 22:38
попробовал))
программо работает:
 
Код

 PFNGLGENBUFFERSARBPROC=procedure(n:GLsizei;buffers:pGLuint);stdcall;
  PFNGLBINDBUFFERARBPROC=procedure(target:GLEnum;buffer:GLuint);stdcall;
  PFNGLBUFFERDATAARBPROC=procedure(target:GLenum;size:GLsizei;data:pGLuint;usage:GLenum);stdcall;
  PFNGLDELETEBUFFERSARBPROC=procedure(n:glsizei;buffers:pgluint);stdcall;
var
  glGenBuffers:PFNGLGENBUFFERSARBPROC=nil;
  glBindBuffer:PFNGLBINDBUFFERARBPROC=nil;
  glBufferData:PFNGLBUFFERDATAARBPROC=nil;
  glDeleteBuffers:PFNGLDELETEBUFFERSARBPROC=nil;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)