PDA

View Full Version : Lazarus/freepascal compile error - how to solve?



paul_nicholls
11-08-2011, 05:35 AM
Hi all,
I have made a DLL that I can compile in Delphi 2010 just fine, but when I try and compile it using Lazarus/freepascal, I get a perplexing error.

Here is the main DLL code:


library xeEngine;
{$I ..\bindings\xeEngine_include.inc}

uses
SysUtils,
xeEngine_audio in 'units\xeEngine_audio.pas',
xeEngine_main in 'units\xeEngine_main.pas',
xeEngine_texture in 'units\xeEngine_texture.pas',
xeEngine_base in 'units\xeEngine_base.pas',
xeEngine_types in '..\bindings\xeEngine_types.pas',
xeEngine_input in 'units\xeEngine_input.pas',
{$ifdef WINDOWS}
xeEngine_window_win in 'units\xeEngine_window_win.pas',
{$endif}
xeEngine_window_types in 'units\xeEngine_window_types.pas',
xEngine_logfile in 'units\xEngine_logfile.pas';

var
EngineObj : TxeEngine;
{$ifdef WINDOWS}
SaveExit : Pointer;
{$endif}

function Engine_GetEngineInst: LongWord; cdecl;
begin
Result := LongWord(EngineObj);
end;

procedure Engine_Initialize; cdecl;
begin
if not Assigned(EngineObj) then
begin
EngineObj := TxeEngine.Create;
end;
end;

procedure Engine_Finalize; cdecl;
begin
if not Assigned(EngineObj) then Exit;

FreeAndNil(EngineObj);
end;

exports
// engine routines
Engine_Initialize,
Engine_Finalize,
Engine_GetEngineInst,
Engine_GetAudio,
Engine_GetInput,
Engine_CreateTexture,
Engine_DestroyObject,
Engine_MakeColor,

// window routines
Window_Create,
Window_UpdateAndRender, //<--- complains about this line!!
Window_Destroy, //<--- complains about this line too!!

// texture routines
Texture_LoadFromFile,
Texture_SetExtents,
Texture_GetExtents,

Texture_Lock,
Texture_SetPixel,
Texture_Unlock,

Texture_Render,
Texture_RenderRect,

// input routines
Input_Update,
Input_KeyIsPressed,
Input_KeyIsReleased,
Input_KeyIsHit,

// logfile routines
LogFile_Clear,
LogFile_SetFileName,
LogFile_LogMessage;

{$ifdef WINDOWS}
procedure LibExit;
begin
Engine_Finalize;

ExitProc := SaveExit; // restore exit procedure chain
end;
{$endif}

begin
EngineObj := nil;

{$ifdef WINDOWS}
SaveExit := ExitProc; // save exit procedure chain
ExitProc := @LibExit; // install LibExit exit procedure

Engine_Initialize;
{$endif}
end.


It is supposed to be exporting routines from the 'xeEngine_window_win' file, but it only finds the 'Window_Create' identifier for some reason - WTF?!?

It is complaining about these lines:


Window_UpdateAndRender, //<--- complains about this line!!
Window_Destroy, //<--- complains about this line too!!


Here is the top section of the xeEngine_window_win file:


unit xeEngine_window_win;
{$I ..\bindings\xeEngine_include.inc}

interface

uses
xeEngine_window_types;

function Window_Create (Title: PWideChar; Width,Height: Word; Fullscreen: Boolean; OnCreateResources: TOnWindowEvent): Boolean; cdecl;
function Window_UpdateAndRender(OnUpdateFrame: TOnUpdateFrame; OnRenderFrame: TOnRenderFrame): Boolean; cdecl;
function Window_Destroy (OnFreeResources: TOnWindowEvent): Boolean; cdecl;

implementation

{snip...}



and here is the include file too just in case:

{$IFDEF VER130} // Delphi 5
{$DEFINE DELPHI5}
{$DEFINE DELPHI5_UP}
{$ENDIF}

{$IFDEF VER140} // Delphi 6
{$DEFINE DELPHI6}
{$DEFINE DELPHI5_UP}
{$DEFINE DELPHI6_UP}
{$ENDIF}

{$IFDEF VER150} // Delphi 7
{$DEFINE DELPHI7}
{$DEFINE DELPHI5_UP}
{$DEFINE DELPHI6_UP}
{$DEFINE DELPHI7_UP}
{$ENDIF}

{$IFDEF VER200} // RAD Studio 2009
{$DEFINE DELPHI12}
{$DEFINE DELPHI2009}
{$DEFINE DELPHI5_UP}
{$DEFINE DELPHI6_UP}
{$DEFINE DELPHI7_UP}
{$DEFINE DELPHI2009_UP}
{$DEFINE UNIC}
{$ENDIF VER200}

{$IFDEF VER210} // RAD Studio 2010
{$DEFINE DELPHI14}
{$DEFINE DELPHI2010}
{$DEFINE DELPHI5_UP}
{$DEFINE DELPHI6_UP}
{$DEFINE DELPHI7_UP}
{$DEFINE DELPHI2009_UP}
{$DEFINE DELPHI2010_UP}
{$DEFINE UNIC}
{$ENDIF VER210}

{$IFDEF VER220} // RAD Studio XE
{$DEFINE DELPHI14}
{$DEFINE DELPHI2010}
{$DEFINE DELPHIXE}
{$DEFINE DELPHI5_UP}
{$DEFINE DELPHI6_UP}
{$DEFINE DELPHI7_UP}
{$DEFINE DELPHI2009_UP}
{$DEFINE DELPHI2010_UP}
{$DEFINE DELPHIXE_UP}
{$DEFINE UNIC}
{$ENDIF VER220}

{$IFDEF DELPHI7_UP}
{$WARN SYMBOL_DEPRECATED OFF}
{$WARN SYMBOL_PLATFORM OFF}
{$WARN UNIT_PLATFORM OFF}
{$WARN UNIT_DEPRECATED OFF}
{$ENDIF}

{$ifdef fpc}
{$mode delphi}

{$ifndef unix}
{$ifndef darwin}
{$ifndef WINDOWS}
{$define WINDOWS}
{$endif}
{$endif}
{$endif}
{$endif}

{$MINENUMSIZE 4}
{$ALIGN ON}

{$ifndef fpc}
{$ifndef WINDOWS}
{$define WINDOWS}
{$endif}
{$endif}

{$H+}

Any ideas? I was feeling really good about all this so far until this moment! :D

cheers,
Paul

paul_nicholls
11-08-2011, 05:46 AM
I googled the error message "Error: The symbol can’t be exported from a library", and found this on a freepascal page:


"Error: The symbol can’t be exported from a library"
You can only export procedures and functions when you write a library. You cannot export variables or constants.

ok, that is all fine and dandy, but aren't I only trying to export a function? with Window_Update and Window_Destroy, they ARE functions like Window_Create...aren't they?!?

this is the xeEngine_window_types file defines in case it matters:

unit xeEngine_window_types;
{$I ..\bindings\xeEngine_include.inc}

interface

type
TOnWindowEvent = procedure(var aExecuting: Boolean) of object;
TOnUpdateFrame = procedure(aTimeSlice: Single; var aExecuting: Boolean) of object;
TOnRenderFrame = procedure(aTimeSlice: Single; var aExecuting: Boolean) of object;

implementation

end.

not...happy...Jan....

cheers,
Paul

Andru
11-08-2011, 11:18 AM
xeEngine_types in '..\bindings\xeEngine_types.pas',
Try do not use something like this. Use -Fu for finding units instead(you can find it somewhere in Project options, if you use Lazarus).

paul_nicholls
11-08-2011, 12:28 PM
Try do not use something like this. Use -Fu for finding units instead(you can find it somewhere in Project options, if you use Lazarus).

Ok, a fair cop :D I will change that, thanks - but does that help me with my compile issue though? I don't know, I will see :)

EDIT: ok, that seems to have fixed my compiler error now - Woo Hoo! Thanks Andru :D

Now the Delphi 2010 test program crashes on finishing when I compile the DLL using Lazarus, but that is another issue :D

cheers,
Pau

Andru
11-08-2011, 12:51 PM
Now the Delphi 2010 test program crashes on finishing when I compile the DLL using Lazarus, but that is another issue
Because there is a difference between size of type Char. Delphi 2009 and higher uses 2 byte per one symbol in String. FreePascal - always 1 byte.

User137
11-08-2011, 01:23 PM
Ain't Lazarus by default using UTF, so some characters reserve 1 byte and others 2. But i recall reading paul had widestring compiler directive, and i'm not sure about that stuff :D

paul_nicholls
11-08-2011, 08:38 PM
I'm not sure about the 2 byte vs 1 byte Char issue....I am passing strings to the DLL using PWideChar. I will have to investigate this further :)

thanks guys :)

cheers,
Paul